clients/memerror
clients/memflush
clients/memparse
+clients/memping
clients/memrm
clients/memslap
clients/memstat
libmemcached/memcached_configure.h
libtest/.hg/
libtest/.hgignore
+libtest/skiptest
libtest/unittest
+libtest/version.h
libtest/wait
libtool
libtool.m4
support/libmemcached.spec
tags
tests/atomsmasher
+tests/c_sasl_test
tests/c_test
tests/cycle
+tests/failure
tests/hash_plus
tests/hashplus
tests/internals
tests/memplus
tests/memslap
tests/output.cmp
+tests/sasl
tests/startservers
tests/testapp
tests/testhashkit
tests/testplus
tests/testudp
tests/var/
+tmp_chroot
unittests/unittests
-libtest/version.h
-clients/memping
-libtest/skiptest
-tests/sasl
-tests/c_sasl_test
--- /dev/null
+#!/bin/bash
+
+if test -f configure; then make clean; make merge-clean; make distclean; fi;
+
+rm -r -f autom4te.cache
+./config/autorun.sh
+./configure
+make
#include "poll/poll.h"
#endif
-#include <assert.h>
+#include <cassert>
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include <ctype.h>
-#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <pthread.h>
#include <signal.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <sys/types.h>
#include <unistd.h>
*
*/
-#include "config.h"
+#include <config.h>
+#include <cstdio>
+#include <cstring>
+#include <getopt.h>
#include <iostream>
-#include <stdio.h>
-#include <inttypes.h>
-#include <string.h>
#include <unistd.h>
-#include <getopt.h>
#include <libmemcached/memcached.h>
#include "utilities.h"
return EXIT_FAILURE;
}
- if (opt_username and initialize_sasl(memc, opt_username, opt_passwd) == false)
+ if (opt_username)
{
- memcached_free(memc);
- return EXIT_FAILURE;
+ memcached_return_t ret;
+ if (memcached_failed(ret= memcached_set_sasl_auth_data(memc, opt_username, opt_passwd)))
+ {
+ std::cerr << memcached_last_error_message(memc) << std::endl;
+ memcached_free(memc);
+ return EXIT_FAILURE;
+ }
}
while (optind < argc)
if (opt_hash)
free(opt_hash);
- shutdown_sasl();
-
return return_code;
}
#include "config.h"
-#include <iostream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <unistd.h>
+#include <cerrno>
+#include <climits>
+#include <cstdio>
+#include <cstdlib>
+#include <cstdlib>
+#include <cstring>
+#include <fcntl.h>
#include <getopt.h>
-#include <sys/types.h>
+#include <iostream>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
#include <sys/stat.h>
#include <sys/types.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <strings.h>
-#include <string.h>
#include <sys/types.h>
-#include <stdlib.h>
-#include <limits.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <libmemcached/memcached.h>
return EXIT_FAILURE;
}
- if (initialize_sasl(memc, opt_username, opt_passwd) == false)
+ if (opt_username)
{
- std::cerr << "Failed to initialize SASL support." << std::endl;
- memcached_free(memc);
- return EXIT_FAILURE;
+ memcached_return_t ret;
+ if (memcached_failed(ret= memcached_set_sasl_auth_data(memc, opt_username, opt_passwd)))
+ {
+ std::cerr << memcached_last_error_message(memc) << std::endl;
+ memcached_free(memc);
+ return EXIT_FAILURE;
+ }
}
while (optind < argc)
free(opt_servers);
if (opt_hash)
free(opt_hash);
- shutdown_sasl();
return return_code;
}
return EXIT_FAILURE;
}
- if (opt_username and initialize_sasl(memc, opt_username, opt_passwd) == false)
+ if (opt_username)
{
- std::cerr << "Failed to initialize SASL support." << std::endl;
-
- memcached_free(memc);
- return EXIT_FAILURE;
+ memcached_return_t ret;
+ if (memcached_failed(ret= memcached_set_sasl_auth_data(memc, opt_username, opt_passwd)))
+ {
+ std::cerr << memcached_last_error_message(memc) << std::endl;
+ memcached_free(memc);
+ return EXIT_FAILURE;
+ }
}
rc= memcached_dump(memc, callbacks, NULL, 1);
if (opt_hash)
free(opt_hash);
- shutdown_sasl();
-
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}
-
- if (!initialize_sasl(memc, opt_username, opt_passwd))
+ if (opt_username)
{
- memcached_free(memc);
- return EXIT_FAILURE;
+ memcached_return_t ret;
+ if (memcached_failed(ret= memcached_set_sasl_auth_data(memc, opt_username, opt_passwd)))
+ {
+ std::cerr << memcached_last_error_message(memc) << std::endl;
+ memcached_free(memc);
+ return EXIT_FAILURE;
+ }
}
rc = memcached_flush(memc, opt_expire);
free(opt_servers);
- shutdown_sasl();
-
return EXIT_SUCCESS;
}
#include <config.h>
#include <cstdio>
+#include <cstring>
#include <iostream>
#include <libmemcached/memcached.h>
free(opt_servers);
- shutdown_sasl();
-
return exit_code;
}
opt_servers= strdup(temp);
else
{
- fprintf(stderr, "No Servers provided\n");
- exit(1);
+ std::cerr << "No Servers provided" << std::endl;
+ return EXIT_FAILURE;
}
}
return EXIT_FAILURE;
}
-
- if (opt_username and initialize_sasl(memc, opt_username, opt_passwd) == false)
+ if (opt_username)
{
- std::cerr << "Failed to initialize SASL support." << std::endl;
-
- memcached_free(memc);
- return EXIT_FAILURE;
+ memcached_return_t ret;
+ if (memcached_failed(ret= memcached_set_sasl_auth_data(memc, opt_username, opt_passwd)))
+ {
+ std::cerr << memcached_last_error_message(memc) << std::endl;
+ memcached_free(memc);
+ return EXIT_FAILURE;
+ }
}
while (optind < argc)
{
if (opt_verbose)
- printf("key: %s\nexpires: %llu\n", argv[optind], (unsigned long long)opt_expire);
- rc = memcached_delete(memc, argv[optind], strlen(argv[optind]), opt_expire);
+ {
+ std::cout << "key: " << argv[optind] << std::endl;
+ std::cout << "expires: " << opt_expire << std::endl;
+ }
+ rc= memcached_delete(memc, argv[optind], strlen(argv[optind]), opt_expire);
- if (rc != MEMCACHED_SUCCESS)
+ if (memcached_failed(rc))
{
- fprintf(stderr, "memrm: %s: memcache error %s",
- argv[optind], memcached_strerror(memc, rc));
+ std::cerr << PROGRAM_NAME << ": " << argv[optind] << ": error " << memcached_strerror(memc, rc) << std::endl;
+
if (memcached_last_error_errno(memc))
- fprintf(stderr, " system error %s", strerror(memcached_last_error_errno(memc)));
- fprintf(stderr, "\n");
+ {
+ std::cerr << " system error " << strerror(memcached_last_error_errno(memc));
+ }
+ std::cerr << std::endl;
return_code= -1;
}
if (opt_hash)
free(opt_hash);
- shutdown_sasl();
-
return return_code;
}
}
}
-
-static char *username;
-static char *passwd;
-
-#if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT
-
-static int get_username(void *context, int id, const char **result, unsigned int *len)
-{
- (void)context;
- if (!result || (id != SASL_CB_USER && id != SASL_CB_AUTHNAME))
- return SASL_BADPARAM;
-
- *result= username;
- if (len)
- {
- *len= (username == NULL) ? 0 : (unsigned int)strlen(username);
- }
-
- return SASL_OK;
-}
-
-static int get_password(sasl_conn_t *conn, void *context, int id,
- sasl_secret_t **psecret)
-{
- (void)context;
- static sasl_secret_t* ptr;
-
- if (!conn || ! psecret || id != SASL_CB_PASS)
- return SASL_BADPARAM;
-
- if (passwd == NULL)
- {
- *psecret= NULL;
- return SASL_OK;
- }
-
- size_t len= strlen(passwd);
- ptr= (sasl_secret_t *)malloc(sizeof(sasl_secret_t) + len +1);
- if (not ptr)
- return SASL_NOMEM;
-
- ptr->len= len;
- memcpy(ptr->data, passwd, len);
- ptr->data[len]= 0;
-
- *psecret= ptr;
- return SASL_OK;
-}
-
-typedef int (*local_sasl_fn)(void);
-
-/* callbacks we support */
-static sasl_callback_t sasl_callbacks[] = {
- { SASL_CB_USER, (local_sasl_fn)get_username, NULL },
- { SASL_CB_AUTHNAME, (local_sasl_fn)get_username, NULL },
- { SASL_CB_PASS, (local_sasl_fn)get_password, NULL },
- { SASL_CB_LIST_END, NULL, NULL }
-};
-
-#endif
-
-bool initialize_sasl(memcached_st *memc, char *user, char *password)
-{
- if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
- {
- return false;
- }
-
- if (memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, (uint64_t)true) == 0)
- {
- return false;
- }
-
- if (user != NULL && password != NULL)
- {
- username= user;
- passwd= password;
-
-#if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT
- if (sasl_client_init(NULL) != SASL_OK)
- {
- fprintf(stderr, "Failed to initialize sasl library!\n");
- return false;
- }
- memcached_set_sasl_callbacks(memc, sasl_callbacks);
-#else
- (void)memc;
-#endif
- }
-
- return true;
-}
-
-void shutdown_sasl(void)
-{
- if (username or passwd)
- {
-#if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT
- sasl_done();
-#endif
- }
-}
-
void initialize_sockets(void)
{
/* Define the function for all platforms to avoid #ifdefs in each program */
#!/bin/sh
-autoreconf -ivf -Wall
+autoreconf --install --force --verbose -Wall
HASHKIT_LIBRARY_VERSION=1:0:0
AC_SUBST(HASHKIT_LIBRARY_VERSION)
-LT_INIT
+LT_PREREQ([2.2])
+LT_INIT()
+LT_LANG([C++])
+LT_LANG([C])
+gl_VISIBILITY
+
m4_include([m4/memcached.m4])
m4_include([m4/memcached_sasl.m4])
+m4_include([m4/gearmand.m4])
AM_CONDITIONAL(BUILDING_LIBMEMCACHED, true)
AM_CONDITIONAL(HAVE_LIBMEMCACHED, false)
-AC_SUBST(_WITH_LIBMEMCACHED_SUPPORT, ["_WITH_LIBMEMCACHED_SUPPORT 1"])
+AC_DEFINE([HAVE_LIBMEMCACHED], [1], [Enables libmemcached Support])
AM_CONDITIONAL(BUILDING_GEARMAN, false)
AM_CONDITIONAL(HAVE_LIBGEARMAN, false)
-AC_SUBST(_WITH_LIBGEARMAN_SUPPORT, ["_WITH_LIBGEARMAN_SUPPORT 0"])
+AC_DEFINE([HAVE_LIBGEARMAN], [0], [Enables libgearman Support])
AC_SEARCH_LIBS(getopt_long, gnugetopt)
AC_SEARCH_LIBS(gethostbyname, nsl)
esac
dnl Specialty checks
-ACX_PTHREAD
+AX_PTHREAD
CONFIG_EXTRA
DETECT_BYTEORDER
ENABLE_UTILLIB
('memcached_get', 'memcached_fetch_result', u'Retrieving data from the server', [u'Brian Aker'], 3),
('memcached_get', 'memcached_get', u'Retrieving data from the server', [u'Brian Aker'], 3),
('memcached_get', 'memcached_get_by_key', u'Retrieving data from the server', [u'Brian Aker'], 3),
+ ('libmemcached/memcached_return_t', 'memcached_return_t', u'Return type values ', [u'Brian Aker'], 3),
('memcached_get', 'memcached_mget', u'Retrieving data from the server', [u'Brian Aker'], 3),
('memcached_get', 'memcached_mget_by_key', u'Retrieving data from the server', [u'Brian Aker'], 3),
('memcached_get', 'memcached_mget_execute', u'Retrieving data from the server', [u'Brian Aker'], 3),
('memcached_get', 'memcached_mget_execute_by_key', u'Retrieving data from the server', [u'Brian Aker'], 3),
+ ('libmemcached/memcached_last_error_message', 'memcached_last_error_message', u'libmemcached Documentation', [u'Brian Aker'], 3),
('memcached_memory_allocators', 'memcached_get_memory_allocators', u'libmemcached Documentation', [u'Brian Aker'], 3),
('memcached_memory_allocators', 'memcached_memory_allocators', u'libmemcached Documentation', [u'Brian Aker'], 3),
('memcached_memory_allocators', 'memcached_set_memory_allocators', u'libmemcached Documentation', [u'Brian Aker'], 3),
('memcached_result_st', 'memcached_result_length', u'Working with result sets', [u'Brian Aker'], 3),
('memcached_result_st', 'memcached_result_st', u'Working with result sets', [u'Brian Aker'], 3),
('memcached_result_st', 'memcached_result_value', u'Working with result sets', [u'Brian Aker'], 3),
- ('libmemcached/memcached_return_t', 'memcached_return_t', u'Return type values ', [u'Brian Aker'], 3),
('memcached_sasl', 'memcached_destroy_sasl_auth_data', u'libmemcached Documentation', [u'Brian Aker'], 3),
('memcached_sasl', 'memcached_get_sasl_callbacks', u'libmemcached Documentation', [u'Brian Aker'], 3),
('memcached_sasl', 'memcached_sasl', u'libmemcached Documentation', [u'Brian Aker'], 3),
docs/man/memcached_server_push.3 \
docs/man/memcached_servers_parse.3 \
docs/man/memcached_set.3 \
+ docs/man/memcached_last_error_message.3 \
docs/man/memcached_set_by_key.3 \
docs/man/memcached_set_memory_allocators.3 \
docs/man/memcached_set_sasl_callbacks.3 \
memcached_create
libmemcached_examples
libmemcached_configuration
- error_messages
-
+ libmemcached/memcached_last_error_message
#################
Working with data
memcached_server_st
memcached_servers
memcached_strerror
+ error_messages
memcached_user_data
memcached_verbosity
memcached_version
--- /dev/null
+=================
+Retrieving errors
+=================
+
+
+--------
+SYNOPSIS
+--------
+
+
+#include <libmemcached/memcached.h>
+
+.. c:function:: const char *memcached_last_error_message(memcached_st *);
+
+Compile and link with -lmemcached
+
+
+-----------
+DESCRIPTION
+-----------
+
+:c:func:`memcached_last_error_message()` is used to return the last error
+message that the server responded too. If this error came from a specific
+server, its hostname and port will be provided in the error message.
+
+------
+RETURN
+------
+
+memcached_last_error_message() returns a const char* which does not need to be
+de-allocated. If no error has occurred then it will return NULL.
+
+----
+HOME
+----
+
+To find out more information please check:
+`http://libmemcached.org/ <http://libmemcached.org/>`_
+
+
+--------
+SEE ALSO
+--------
+
+:manpage:`memcached(1)` :manpage:`libmemcached(3)` :manpage:`memcached_strerror(3)`
+
+
-.TH "HASHKIT_CLONE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_CLONE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_clone \- libhashkit Documentation
.
-.TH "HASHKIT_CRC32" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_CRC32" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_crc32 \- libhashkit Documentation
.
-.TH "HASHKIT_CREATE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_CREATE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_create \- libhashkit Documentation
.
-.TH "HASHKIT_FNV1_32" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_FNV1_32" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_fnv1_32 \- libhashkit Documentation
.
-.TH "HASHKIT_FNV1_64" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_FNV1_64" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_fnv1_64 \- libhashkit Documentation
.
-.TH "HASHKIT_FNV1A_32" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_FNV1A_32" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_fnv1a_32 \- libhashkit Documentation
.
-.TH "HASHKIT_FNV1A_64" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_FNV1A_64" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_fnv1a_64 \- libhashkit Documentation
.
-.TH "HASHKIT_FREE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_FREE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_free \- libhashkit Documentation
.
-.TH "HASHKIT_FUNCTIONS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_FUNCTIONS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_functions \- libhashkit Documentation
.
-.TH "HASHKIT_HSIEH" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_HSIEH" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_hsieh \- libhashkit Documentation
.
-.TH "HASHKIT_IS_ALLOCATED" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_IS_ALLOCATED" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_is_allocated \- libhashkit Documentation
.
-.TH "HASHKIT_JENKINS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_JENKINS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_jenkins \- libhashkit Documentation
.
-.TH "HASHKIT_MD5" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_MD5" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_md5 \- libhashkit Documentation
.
-.TH "HASHKIT_MURMUR" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_MURMUR" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_murmur \- libhashkit Documentation
.
-.TH "HASHKIT_VALUE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "HASHKIT_VALUE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
hashkit_value \- libhashkit Documentation
.
-.TH "LIBHASHKIT" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "LIBHASHKIT" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
libhashkit \- libhashkit Documentation
.
-.TH "LIBMEMCACHED" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "LIBMEMCACHED" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
libmemcached \- Introducing the C Client Library for memcached
.
-.TH "LIBMEMCACHED_CHECK_CONFIGURATION" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "LIBMEMCACHED_CHECK_CONFIGURATION" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
libmemcached_check_configuration \- libmemcached Documentation
.
-.TH "LIBMEMCACHED_CONFIGURATION" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "LIBMEMCACHED_CONFIGURATION" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
libmemcached_configuration \- libmemcached Documentation
.
-.TH "LIBMEMCACHED_EXAMPLES" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "LIBMEMCACHED_EXAMPLES" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
libmemcached_examples \- libmemcached Documentation
.
-.TH "LIBMEMCACHEDUTIL" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "LIBMEMCACHEDUTIL" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
libmemcachedutil \- libmemcached Documentation
.
-.TH "MEMASLAP" "1" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMASLAP" "1" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memaslap \- libmemcached Documentation
.
-.TH "MEMCACHED" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached \- libmemcached Documentation
.
-.TH "MEMCACHED_ADD" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_ADD" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_add \- Storing and Replacing Data
.
-.TH "MEMCACHED_ADD_BY_KEY" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_ADD_BY_KEY" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_add_by_key \- Storing and Replacing Data
.
-.TH "MEMCACHED_ANALYZE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_ANALYZE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_analyze \- libmemcached Documentation
.
-.TH "MEMCACHED_APPEND" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_APPEND" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_append \- Appending to or Prepending to data on the server
.
-.TH "MEMCACHED_APPEND_BY_KEY" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_APPEND_BY_KEY" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_append_by_key \- Appending to or Prepending to data on the server
.
-.TH "MEMCACHED_AUTO" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_AUTO" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_auto \- Incrementing and Decrementing Values
.
-.TH "MEMCACHED_BEHAVIOR" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_BEHAVIOR" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_behavior \- libmemcached Documentation
.
.B MEMCACHED_BEHAVIOR_RETRY_TIMEOUT
.UNINDENT
.sp
-When enabled a host which is problematic will only be checked for usage based on the amount of time set by this behavior.
+When enabled a host which is problematic will only be checked for usage based on the amount of time set by this behavior. The value is in seconds.
.INDENT 0.0
.TP
.B MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY
-.TH "MEMCACHED_BEHAVIOR_GET" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_BEHAVIOR_GET" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_behavior_get \- libmemcached Documentation
.
.B MEMCACHED_BEHAVIOR_RETRY_TIMEOUT
.UNINDENT
.sp
-When enabled a host which is problematic will only be checked for usage based on the amount of time set by this behavior.
+When enabled a host which is problematic will only be checked for usage based on the amount of time set by this behavior. The value is in seconds.
.INDENT 0.0
.TP
.B MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY
-.TH "MEMCACHED_BEHAVIOR_SET" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_BEHAVIOR_SET" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_behavior_set \- libmemcached Documentation
.
.B MEMCACHED_BEHAVIOR_RETRY_TIMEOUT
.UNINDENT
.sp
-When enabled a host which is problematic will only be checked for usage based on the amount of time set by this behavior.
+When enabled a host which is problematic will only be checked for usage based on the amount of time set by this behavior. The value is in seconds.
.INDENT 0.0
.TP
.B MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY
-.TH "MEMCACHED_CALLBACK" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_CALLBACK" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_callback \- libmemcached Documentation
.
-.TH "MEMCACHED_CALLBACK_GET" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_CALLBACK_GET" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_callback_get \- libmemcached Documentation
.
-.TH "MEMCACHED_CALLBACK_SET" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_CALLBACK_SET" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_callback_set \- libmemcached Documentation
.
-.TH "MEMCACHED_CAS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_CAS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_cas \- Working with data on the server in an atomic fashion
.
-.TH "MEMCACHED_CAS_BY_KEY" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_CAS_BY_KEY" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_cas_by_key \- Storing and Replacing Data
.
-.TH "MEMCACHED_CLONE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_CLONE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_clone \- libmemcached Documentation
.
-.TH "MEMCACHED_CREATE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_CREATE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_create \- libmemcached Documentation
.
-.TH "MEMCACHED_DECREMENT" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_DECREMENT" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_decrement \- Incrementing and Decrementing Values
.
-.TH "MEMCACHED_DECREMENT_WITH_INITIAL" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_DECREMENT_WITH_INITIAL" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_decrement_with_initial \- Incrementing and Decrementing Values
.
-.TH "MEMCACHED_DELETE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_DELETE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_delete \- libmemcached Documentation
.
-.TH "MEMCACHED_DELETE_BY_KEY" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_DELETE_BY_KEY" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_delete_by_key \- libmemcached Documentation
.
-.TH "MEMCACHED_DESTROY_SASL_AUTH_DATA" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_DESTROY_SASL_AUTH_DATA" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_destroy_sasl_auth_data \- libmemcached Documentation
.
-.TH "MEMCACHED_DUMP" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_DUMP" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_dump \- libmemcached Documentation
.
-.TH "MEMCACHED_FETCH" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_FETCH" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_fetch \- Retrieving data from the server
.
-.TH "MEMCACHED_FETCH_EXECUTE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_FETCH_EXECUTE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_fetch_execute \- Retrieving data from the server
.
-.TH "MEMCACHED_FETCH_RESULT" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_FETCH_RESULT" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_fetch_result \- Retrieving data from the server
.
-.TH "MEMCACHED_FLUSH" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_FLUSH" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_flush \- libmemcached Documentation
.
-.TH "MEMCACHED_FLUSH_BUFFERS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_FLUSH_BUFFERS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_flush_buffers \- libmemcached Documentation
.
-.TH "MEMCACHED_FREE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_FREE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_free \- libmemcached Documentation
.
-.TH "MEMCACHED_GENERATE_HASH" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_GENERATE_HASH" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_generate_hash \- Generating hash values directly
.
-.TH "MEMCACHED_GENERATE_HASH_VALUE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_GENERATE_HASH_VALUE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_generate_hash_value \- Generating hash values directly
.
-.TH "MEMCACHED_GET" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_GET" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_get \- Retrieving data from the server
.
-.TH "MEMCACHED_GET_BY_KEY" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_GET_BY_KEY" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_get_by_key \- Retrieving data from the server
.
-.TH "MEMCACHED_GET_MEMORY_ALLOCATORS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_GET_MEMORY_ALLOCATORS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_get_memory_allocators \- libmemcached Documentation
.
-.TH "MEMCACHED_GET_SASL_CALLBACKS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_GET_SASL_CALLBACKS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_get_sasl_callbacks \- libmemcached Documentation
.
-.TH "MEMCACHED_GET_USER_DATA" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_GET_USER_DATA" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_get_user_data \- libmemcached Documentation
.
-.TH "MEMCACHED_INCREMENT" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_INCREMENT" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_increment \- Incrementing and Decrementing Values
.
-.TH "MEMCACHED_INCREMENT_WITH_INITIAL" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_INCREMENT_WITH_INITIAL" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_increment_with_initial \- Incrementing and Decrementing Values
.
--- /dev/null
+.TH "MEMCACHED_LAST_ERROR_MESSAGE" "3" "September 09, 2011" "0.52" "libmemcached"
+.SH NAME
+memcached_last_error_message \- libmemcached Documentation
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructeredText.
+.
+.SH SYNOPSIS
+.sp
+#include <libmemcached/memcached.h>
+.INDENT 0.0
+.TP
+.B const char *memcached_last_error_message(memcached_st *);
+.UNINDENT
+.sp
+Compile and link with \-lmemcached
+.SH DESCRIPTION
+.sp
+\fBmemcached_last_error_message()\fP is used to return the last error
+message that the server responded too. If this error came from a specific
+server, its hostname and port will be provided in the error message.
+.SH RETURN
+.sp
+memcached_last_error_message() returns a const char* which does not need to be
+de\-allocated. If no error has occurred then it will return NULL.
+.SH HOME
+.sp
+To find out more information please check:
+\fI\%http://libmemcached.org/\fP
+.SH SEE ALSO
+.sp
+\fImemcached(1)\fP \fIlibmemcached(3)\fP \fImemcached_strerror(3)\fP
+.SH AUTHOR
+Brian Aker
+.SH COPYRIGHT
+2011, Brian Aker DataDifferential, http://datadifferential.com/
+.\" Generated by docutils manpage writer.
+.\"
+.
-.TH "MEMCACHED_LIB_VERSION" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_LIB_VERSION" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_lib_version \- libmemcached Documentation
.
-.TH "MEMCACHED_MEMORY_ALLOCATORS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_MEMORY_ALLOCATORS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_memory_allocators \- libmemcached Documentation
.
-.TH "MEMCACHED_MGET" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_MGET" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_mget \- Retrieving data from the server
.
-.TH "MEMCACHED_MGET_BY_KEY" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_MGET_BY_KEY" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_mget_by_key \- Retrieving data from the server
.
-.TH "MEMCACHED_MGET_EXECUTE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_MGET_EXECUTE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_mget_execute \- Retrieving data from the server
.
-.TH "MEMCACHED_MGET_EXECUTE_BY_KEY" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_MGET_EXECUTE_BY_KEY" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_mget_execute_by_key \- Retrieving data from the server
.
-.TH "MEMCACHED_POOL" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_POOL" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_pool \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_BEHAVIOR_GET" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_POOL_BEHAVIOR_GET" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_pool_behavior_get \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_BEHAVIOR_SET" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_POOL_BEHAVIOR_SET" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_pool_behavior_set \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_CREATE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_POOL_CREATE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_pool_create \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_DESTROY" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_POOL_DESTROY" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_pool_destroy \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_POP" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_POOL_POP" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_pool_pop \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_PUSH" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_POOL_PUSH" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_pool_push \- libmemcached Documentation
.
-.TH "MEMCACHED_POOL_ST" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_POOL_ST" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_pool_st \- libmemcached Documentation
.
-.TH "MEMCACHED_PREPEND" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_PREPEND" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_prepend \- Appending to or Prepending to data on the server
.
-.TH "MEMCACHED_PREPEND_BY_KEY" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_PREPEND_BY_KEY" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_prepend_by_key \- Appending to or Prepending to data on the server
.
-.TH "MEMCACHED_QUIT" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_QUIT" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_quit \- libmemcached Documentation
.
-.TH "MEMCACHED_REPLACE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_REPLACE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_replace \- Storing and Replacing Data
.
-.TH "MEMCACHED_REPLACE_BY_KEY" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_REPLACE_BY_KEY" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_replace_by_key \- Storing and Replacing Data
.
-.TH "MEMCACHED_RESULT_CAS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_RESULT_CAS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_result_cas \- Working with result sets
.
-.TH "MEMCACHED_RESULT_CREATE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_RESULT_CREATE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_result_create \- Working with result sets
.
-.TH "MEMCACHED_RESULT_FLAGS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_RESULT_FLAGS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_result_flags \- Working with result sets
.
-.TH "MEMCACHED_RESULT_FREE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_RESULT_FREE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_result_free \- Working with result sets
.
-.TH "MEMCACHED_RESULT_KEY_LENGTH" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_RESULT_KEY_LENGTH" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_result_key_length \- Working with result sets
.
-.TH "MEMCACHED_RESULT_KEY_VALUE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_RESULT_KEY_VALUE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_result_key_value \- Working with result sets
.
-.TH "MEMCACHED_RESULT_LENGTH" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_RESULT_LENGTH" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_result_length \- Working with result sets
.
-.TH "MEMCACHED_RESULT_ST" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_RESULT_ST" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_result_st \- Working with result sets
.
-.TH "MEMCACHED_RESULT_VALUE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_RESULT_VALUE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_result_value \- Working with result sets
.
-.TH "MEMCACHED_SASL" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SASL" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_sasl \- libmemcached Documentation
.
-.TH "MEMCACHED_SASL_SET_AUTH_DATA" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SASL_SET_AUTH_DATA" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_sasl_set_auth_data \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_ADD" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SERVER_ADD" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_server_add \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_ADD_UNIX_SOCKET" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SERVER_ADD_UNIX_SOCKET" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_server_add_unix_socket \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_COUNT" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SERVER_COUNT" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_server_count \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_CURSOR" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SERVER_CURSOR" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_server_cursor \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_LIST" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SERVER_LIST" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_server_list \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_LIST_APPEND" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SERVER_LIST_APPEND" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_server_list_append \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_LIST_COUNT" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SERVER_LIST_COUNT" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_server_list_count \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_LIST_FREE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SERVER_LIST_FREE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_server_list_free \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_PUSH" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SERVER_PUSH" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_server_push \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVER_ST" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SERVER_ST" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_server_st \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVERS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SERVERS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_servers \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVERS_PARSE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SERVERS_PARSE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_servers_parse \- libmemcached Documentation
.
-.TH "MEMCACHED_SERVERS_RESET" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SERVERS_RESET" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_servers_reset \- libmemcached Documentation
.
-.TH "MEMCACHED_SET" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SET" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_set \- Storing and Replacing Data
.
-.TH "MEMCACHED_SET_BY_KEY" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SET_BY_KEY" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_set_by_key \- Storing and Replacing Data
.
-.TH "MEMCACHED_SET_MEMORY_ALLOCATORS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SET_MEMORY_ALLOCATORS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_set_memory_allocators \- libmemcached Documentation
.
-.TH "MEMCACHED_SET_MEMORY_ALLOCATORS_CONTEXT" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SET_MEMORY_ALLOCATORS_CONTEXT" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_set_memory_allocators_context \- libmemcached Documentation
.
-.TH "MEMCACHED_SET_SASL_CALLBACKS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SET_SASL_CALLBACKS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_set_sasl_callbacks \- libmemcached Documentation
.
-.TH "MEMCACHED_SET_USER_DATA" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_SET_USER_DATA" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_set_user_data \- libmemcached Documentation
.
-.TH "MEMCACHED_STAT" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_STAT" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_stat \- libmemcached Documentation
.
-.TH "MEMCACHED_STAT_EXECUTE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_STAT_EXECUTE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_stat_execute \- libmemcached Documentation
.
-.TH "MEMCACHED_STAT_GET_KEYS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_STAT_GET_KEYS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_stat_get_keys \- libmemcached Documentation
.
-.TH "MEMCACHED_STAT_GET_VALUE" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_STAT_GET_VALUE" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_stat_get_value \- libmemcached Documentation
.
-.TH "MEMCACHED_STAT_SERVERNAME" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_STAT_SERVERNAME" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_stat_servername \- libmemcached Documentation
.
-.TH "MEMCACHED_STATS" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_STATS" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_stats \- libmemcached Documentation
.
-.TH "MEMCACHED_STRERROR" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_STRERROR" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_strerror \- libmemcached Documentation
.
-.TH "MEMCACHED_USER_DATA" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_USER_DATA" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_user_data \- libmemcached Documentation
.
-.TH "MEMCACHED_VERBOSITY" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_VERBOSITY" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_verbosity \- libmemcached Documentation
.
-.TH "MEMCACHED_VERSION" "3" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCACHED_VERSION" "3" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcached_version \- libmemcached Documentation
.
-.TH "MEMCAPABLE" "1" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCAPABLE" "1" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcapable \- libmemcached Documentation
.
-.TH "MEMCAT" "1" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCAT" "1" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcat \- libmemcached Documentation
.
-.TH "MEMCP" "1" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMCP" "1" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memcp \- libmemcached Documentation
.
-.TH "MEMDUMP" "1" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMDUMP" "1" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memdump \- libmemcached Documentation
.
-.TH "MEMERROR" "1" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMERROR" "1" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memerror \- libmemcached Documentation
.
-.TH "MEMFLUSH" "1" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMFLUSH" "1" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memflush \- libmemcached Documentation
.
-.TH "MEMRM" "1" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMRM" "1" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memrm \- libmemcached Documentation
.
-.TH "MEMSLAP" "1" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMSLAP" "1" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memslap \- libmemcached Documentation
.
-.TH "MEMSTAT" "1" "July 21, 2011" "0.51" "libmemcached"
+.TH "MEMSTAT" "1" "September 09, 2011" "0.52" "libmemcached"
.SH NAME
memstat \- libmemcached Documentation
.
.. c:type:: MEMCACHED_BEHAVIOR_RETRY_TIMEOUT
-When enabled a host which is problematic will only be checked for usage based on the amount of time set by this behavior.
+When enabled a host which is problematic will only be checked for usage based on the amount of time set by this behavior. The value is in seconds.
.. c:type:: MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY
* in the protocol library. You might want to have your copy of the protocol
* specification next to your coffee ;-)
*/
+
#include "config.h"
+
#include <assert.h>
#include <sys/types.h>
#include <stdio.h>
* @brief HashKit Header
*/
-#ifndef HASHKIT_ALGORITHM_H
-#define HASHKIT_ALGORITHM_H
+#pragma once
#ifdef __cplusplus
extern "C" {
#ifdef __cplusplus
}
#endif
-
-#endif /* HASHKIT_ALGORITHM_H */
* @brief HashKit Header
*/
-#ifndef HASHKIT_BEHAVIOR_H
-#define HASHKIT_BEHAVIOR_H
+#pragma once
#ifdef __cplusplus
extern "C" {
#ifdef __cplusplus
}
#endif
-
-#endif /* HASHKIT_BEHAVIOR_H */
* Use and distribution licensed under the BSD license. See
* the COPYING file in the parent directory for full text.
*/
-#ifndef LIBHASHKIT_CONFIGURE_H
-#define LIBHASHKIT_CONFIGURE_H
+
+#pragma once
#ifdef __cplusplus
extern "C" {
#ifdef __cplusplus
}
#endif
-
-#endif /* LIBHASHKIT_CONFIGURE_H */
case HASHKIT_HASH_CUSTOM:
case HASHKIT_HASH_MAX:
default:
-#ifdef HAVE_DEBUG
- fprintf(stderr, "hashkit_hash_t was extended but libhashkit_generate_value was not updated\n");
- fflush(stderr);
- assert(0);
-#endif
+ if (DEBUG)
+ {
+ fprintf(stderr, "hashkit_hash_t was extended but libhashkit_generate_value was not updated\n");
+ fflush(stderr);
+ assert(0);
+ }
break;
}
* the COPYING file in the parent directory for full text.
*/
-#ifndef HASHKIT_DIGEST_H
-#define HASHKIT_DIGEST_H
+#pragma once
#ifdef __cplusplus
extern "C" {
#ifdef __cplusplus
}
#endif
-
-#endif /* HASHKIT_DIGEST_H */
libhashkit_libhashkit_la_SOURCES+= libhashkit/murmur.cc
endif
-libhashkit_libhashkit_la_CPPFLAGS= \
- ${AM_CPPFLAGS} \
- -DBUILDING_HASHKIT
+libhashkit_libhashkit_la_CPPFLAGS= -DBUILDING_HASHKIT
-libhashkit_libhashkit_la_CFLAGS= \
- ${AM_CFLAGS} \
- -DBUILDING_HASHKIT
+libhashkit_libhashkit_la_CFLAGS= -DBUILDING_HASHKIT
-libhashkit_libhashkit_la_CXXFLAGS= \
- ${AM_CXXFLAGS} \
- -DBUILDING_HASHKIT
+libhashkit_libhashkit_la_CXXFLAGS= -DBUILDING_HASHKIT
libhashkit_libhashkit_la_LDFLAGS= \
$(LIBM) \
void _libmemcached_free(const memcached_st*, void *mem, void*)
{
if (mem)
+ {
free(mem);
+ }
}
void *_libmemcached_malloc(const memcached_st *, size_t size, void *)
{
void *ret = _libmemcached_malloc(self, nelem * size, context);
if (not ret)
+ {
memset(ret, 0, nelem * size);
+ }
return ret;
}
memcached_calloc_fn mem_calloc,
void *context)
{
+ if (self == NULL)
+ {
+ return MEMCACHED_INVALID_ARGUMENTS;
+ }
+
/* All should be set, or none should be set */
if (mem_malloc == NULL && mem_free == NULL && mem_realloc == NULL && mem_calloc == NULL)
{
}
else if (mem_malloc == NULL || mem_free == NULL || mem_realloc == NULL || mem_calloc == NULL)
{
- return MEMCACHED_FAILURE;
+ return memcached_set_error(*self, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, memcached_literal_param("NULL parameter provided for one or more allocators"));
}
else
{
memcached_realloc_fn *mem_realloc,
memcached_calloc_fn *mem_calloc)
{
+ if (self == NULL)
+ {
+ return;
+ }
+
*mem_malloc= self->allocators.malloc;
*mem_free= self->allocators.free;
*mem_realloc= self->allocators.realloc;
#endif
LIBMEMCACHED_LOCAL
-memcached_array_st *memcached_array_clone(memcached_st *memc, const memcached_array_st *original);
+memcached_array_st *memcached_array_clone(struct memcached_st *memc, const memcached_array_st *original);
LIBMEMCACHED_LOCAL
-memcached_array_st *memcached_strcpy(memcached_st *memc, const char *str, size_t str_length);
+memcached_array_st *memcached_strcpy(struct memcached_st *memc, const char *str, size_t str_length);
LIBMEMCACHED_LOCAL
void memcached_array_free(memcached_array_st *array);
uint64_t data)
{
if (not ptr)
+ {
return MEMCACHED_INVALID_ARGUMENTS;
+ }
switch (flag)
{
ptr->flags.auto_eject_hosts= bool(data);
case MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT:
- ptr->server_failure_limit= (uint32_t)data;
+ if (data == 0)
+ {
+ return memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
+ memcached_literal_param("MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT requires a value greater then zero."));
+ }
+ ptr->server_failure_limit= uint32_t(data);
break;
case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL:
break;
case MEMCACHED_BEHAVIOR_RETRY_TIMEOUT:
- ptr->retry_timeout= (int32_t)data;
+ if (data == 0)
+ {
+ return memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
+ memcached_literal_param("MEMCACHED_BEHAVIOR_RETRY_TIMEOUT requires a value greater then zero."));
+ }
+ ptr->retry_timeout= int32_t(data);
break;
case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE:
{
ptr->ketama.weighted= false;
}
+
ptr->distribution= type;
run_distribution(ptr);
+
return MEMCACHED_SUCCESS;
}
#include <libmemcached/common.h>
#include <sys/types.h>
+#ifndef __INTEL_COMPILER
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif
/*
These functions provide data and function callback support
#include <sys/types.h>
#include <unistd.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
#include <libmemcached/memcached.h>
#include <libmemcached/watchpoint.h>
#include <libmemcached/is.h>
#ifdef __cplusplus
#include <libmemcached/backtrace.hpp>
#include <libmemcached/assert.hpp>
+#include <libmemcached/server.hpp>
#endif
#include <libmemcached/continuum.hpp>
#define memcached_server_response_decrement(A) (A)->cursor_active--
#define memcached_server_response_reset(A) (A)->cursor_active=0
-LIBMEMCACHED_LOCAL
-void set_last_disconnected_host(memcached_server_write_instance_st ptr);
-
#ifdef __cplusplus
LIBMEMCACHED_LOCAL
memcached_return_t memcached_key_test(const memcached_st& memc,
LIBMEMCACHED_LOCAL
memcached_return_t memcached_purge(memcached_server_write_instance_st ptr);
-LIBMEMCACHED_LOCAL
- memcached_server_st *__server_create_with(const memcached_st *memc,
- memcached_server_write_instance_st host,
- const char *hostname,
- in_port_t port,
- uint32_t weight,
- memcached_connection_t type);
-
static inline memcached_return_t memcached_validate_key_length(size_t key_length, bool binary)
{
#include <libmemcached/common.h>
+
+#include <cassert>
#include <ctime>
#include <sys/time.h>
-static memcached_return_t connect_poll(memcached_server_st *ptr)
+static memcached_return_t connect_poll(memcached_server_st *server)
{
struct pollfd fds[1];
- fds[0].fd = ptr->fd;
- fds[0].events = POLLOUT;
+ fds[0].fd= server->fd;
+ fds[0].events= POLLOUT;
size_t loop_max= 5;
- if (ptr->root->poll_timeout == 0)
+ if (server->root->poll_timeout == 0)
{
- return memcached_set_error(*ptr, MEMCACHED_TIMEOUT, MEMCACHED_AT);
+ return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT);
}
while (--loop_max) // Should only loop on cases of ERESTART or EINTR
{
- int error= poll(fds, 1, ptr->root->connect_timeout);
+ int error= poll(fds, 1, server->root->connect_timeout);
switch (error)
{
case 1:
{
int err;
socklen_t len= sizeof (err);
- (void)getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len);
+ (void)getsockopt(server->fd, SOL_SOCKET, SO_ERROR, &err, &len);
// We check the value to see what happened wth the socket.
if (err == 0)
return MEMCACHED_SUCCESS;
}
- return memcached_set_errno(*ptr, err, MEMCACHED_AT);
+ return memcached_set_errno(*server, err, MEMCACHED_AT);
}
case 0:
{
- return memcached_set_error(*ptr, MEMCACHED_TIMEOUT, MEMCACHED_AT);
+ return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT);
}
default: // A real error occurred and we need to completely bail
case EFAULT:
case ENOMEM:
- return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT);
+ return memcached_set_error(*server, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT);
case EINVAL:
- return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, memcached_literal_param("RLIMIT_NOFILE exceeded, or if OSX the timeout value was invalid"));
+ return memcached_set_error(*server, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, memcached_literal_param("RLIMIT_NOFILE exceeded, or if OSX the timeout value was invalid"));
default: // This should not happen
if (fds[0].revents & POLLERR)
{
int err;
socklen_t len= sizeof (err);
- (void)getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len);
- memcached_set_errno(*ptr, (err == 0) ? get_socket_errno() : err, MEMCACHED_AT);
+ (void)getsockopt(server->fd, SOL_SOCKET, SO_ERROR, &err, &len);
+ memcached_set_errno(*server, (err == 0) ? get_socket_errno() : err, MEMCACHED_AT);
}
else
{
- memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
+ memcached_set_errno(*server, get_socket_errno(), MEMCACHED_AT);
}
- assert_msg(ptr->fd != INVALID_SOCKET, "poll() was passed an invalid file descriptor");
- (void)closesocket(ptr->fd);
- ptr->fd= INVALID_SOCKET;
- ptr->state= MEMCACHED_SERVER_STATE_NEW;
+ assert_msg(server->fd != INVALID_SOCKET, "poll() was passed an invalid file descriptor");
+ (void)closesocket(server->fd);
+ server->fd= INVALID_SOCKET;
+ server->state= MEMCACHED_SERVER_STATE_NEW;
- return memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
+ return memcached_set_errno(*server, get_socket_errno(), MEMCACHED_AT);
}
}
}
// This should only be possible from ERESTART or EINTR;
- return memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
+ return memcached_set_errno(*server, get_socket_errno(), MEMCACHED_AT);
}
static memcached_return_t set_hostinfo(memcached_server_st *server)
hints.ai_protocol= IPPROTO_TCP;
}
+ server->address_info= NULL;
int errcode;
switch(errcode= getaddrinfo(server->hostname, str_port, &hints, &server->address_info))
{
return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT, memcached_string_make_from_cstr(gai_strerror(errcode)));
case EAI_SYSTEM:
- return memcached_set_errno(*server, errno, MEMCACHED_AT, memcached_literal_param("getaddrinfo(EAI_SYSTEM)"));
+ return memcached_set_errno(*server, errno, MEMCACHED_AT, memcached_literal_param("getaddrinfo(EAI_SYSTEM)"));
case EAI_BADFLAGS:
return memcached_set_error(*server, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, memcached_literal_param("getaddrinfo(EAI_BADFLAGS)"));
return MEMCACHED_SUCCESS;
}
-static inline void set_socket_nonblocking(memcached_server_st *ptr)
+static inline void set_socket_nonblocking(memcached_server_st *server)
{
#ifdef WIN32
- u_long arg = 1;
- if (ioctlsocket(ptr->fd, FIONBIO, &arg) == SOCKET_ERROR)
+ u_long arg= 1;
+ if (ioctlsocket(server->fd, FIONBIO, &arg) == SOCKET_ERROR)
{
- memcached_set_errno(*ptr, get_socket_errno(), NULL);
+ memcached_set_errno(*server, get_socket_errno(), NULL);
}
#else
int flags;
do
{
- flags= fcntl(ptr->fd, F_GETFL, 0);
+ flags= fcntl(server->fd, F_GETFL, 0);
} while (flags == -1 && (errno == EINTR || errno == EAGAIN));
if (flags == -1)
{
- memcached_set_errno(*ptr, errno, NULL);
+ memcached_set_errno(*server, errno, NULL);
}
else if ((flags & O_NONBLOCK) == 0)
{
do
{
- rval= fcntl(ptr->fd, F_SETFL, flags | O_NONBLOCK);
+ rval= fcntl(server->fd, F_SETFL, flags | O_NONBLOCK);
} while (rval == -1 && (errno == EINTR || errno == EAGAIN));
unlikely (rval == -1)
{
- memcached_set_errno(*ptr, errno, NULL);
+ memcached_set_errno(*server, errno, NULL);
}
}
#endif
}
-static void set_socket_options(memcached_server_st *ptr)
+static void set_socket_options(memcached_server_st *server)
{
- assert_msg(ptr->fd != -1, "invalid socket was passed to set_socket_options()");
+ assert_msg(server->fd != -1, "invalid socket was passed to set_socket_options()");
- if (ptr->type == MEMCACHED_CONNECTION_UDP)
+ if (server->type == MEMCACHED_CONNECTION_UDP)
{
return;
}
#ifdef HAVE_SNDTIMEO
- if (ptr->root->snd_timeout)
+ if (server->root->snd_timeout)
{
int error;
struct timeval waittime;
waittime.tv_sec= 0;
- waittime.tv_usec= ptr->root->snd_timeout;
+ waittime.tv_usec= server->root->snd_timeout;
- error= setsockopt(ptr->fd, SOL_SOCKET, SO_SNDTIMEO,
+ error= setsockopt(server->fd, SOL_SOCKET, SO_SNDTIMEO,
&waittime, (socklen_t)sizeof(struct timeval));
WATCHPOINT_ASSERT(error == 0);
}
#endif
#ifdef HAVE_RCVTIMEO
- if (ptr->root->rcv_timeout)
+ if (server->root->rcv_timeout)
{
int error;
struct timeval waittime;
waittime.tv_sec= 0;
- waittime.tv_usec= ptr->root->rcv_timeout;
+ waittime.tv_usec= server->root->rcv_timeout;
- error= setsockopt(ptr->fd, SOL_SOCKET, SO_RCVTIMEO,
+ error= setsockopt(server->fd, SOL_SOCKET, SO_RCVTIMEO,
&waittime, (socklen_t)sizeof(struct timeval));
WATCHPOINT_ASSERT(error == 0);
}
#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
{
int set= 1;
- int error= setsockopt(ptr->fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
+ int error= setsockopt(server->fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
// This is not considered a fatal error
if (error == -1)
}
#endif
- if (ptr->root->flags.no_block)
+ if (server->root->flags.no_block)
{
int error;
struct linger linger;
linger.l_onoff= 1;
linger.l_linger= 0; /* By default on close() just drop the socket */
- error= setsockopt(ptr->fd, SOL_SOCKET, SO_LINGER,
+ error= setsockopt(server->fd, SOL_SOCKET, SO_LINGER,
&linger, (socklen_t)sizeof(struct linger));
WATCHPOINT_ASSERT(error == 0);
}
- if (ptr->root->flags.tcp_nodelay)
+ if (server->root->flags.tcp_nodelay)
{
int flag= 1;
int error;
- error= setsockopt(ptr->fd, IPPROTO_TCP, TCP_NODELAY,
+ error= setsockopt(server->fd, IPPROTO_TCP, TCP_NODELAY,
&flag, (socklen_t)sizeof(int));
WATCHPOINT_ASSERT(error == 0);
}
- if (ptr->root->flags.tcp_keepalive)
+ if (server->root->flags.tcp_keepalive)
{
int flag= 1;
int error;
- error= setsockopt(ptr->fd, SOL_SOCKET, SO_KEEPALIVE,
+ error= setsockopt(server->fd, SOL_SOCKET, SO_KEEPALIVE,
&flag, (socklen_t)sizeof(int));
WATCHPOINT_ASSERT(error == 0);
}
#ifdef TCP_KEEPIDLE
- if (ptr->root->tcp_keepidle > 0)
+ if (server->root->tcp_keepidle > 0)
{
int error;
- error= setsockopt(ptr->fd, IPPROTO_TCP, TCP_KEEPIDLE,
- &ptr->root->tcp_keepidle, (socklen_t)sizeof(int));
+ error= setsockopt(server->fd, IPPROTO_TCP, TCP_KEEPIDLE,
+ &server->root->tcp_keepidle, (socklen_t)sizeof(int));
WATCHPOINT_ASSERT(error == 0);
}
#endif
- if (ptr->root->send_size > 0)
+ if (server->root->send_size > 0)
{
int error;
- error= setsockopt(ptr->fd, SOL_SOCKET, SO_SNDBUF,
- &ptr->root->send_size, (socklen_t)sizeof(int));
+ error= setsockopt(server->fd, SOL_SOCKET, SO_SNDBUF,
+ &server->root->send_size, (socklen_t)sizeof(int));
WATCHPOINT_ASSERT(error == 0);
}
- if (ptr->root->recv_size > 0)
+ if (server->root->recv_size > 0)
{
int error;
- error= setsockopt(ptr->fd, SOL_SOCKET, SO_RCVBUF,
- &ptr->root->recv_size, (socklen_t)sizeof(int));
+ error= setsockopt(server->fd, SOL_SOCKET, SO_RCVBUF,
+ &server->root->recv_size, (socklen_t)sizeof(int));
WATCHPOINT_ASSERT(error == 0);
}
/* libmemcached will always use nonblocking IO to avoid write deadlocks */
- set_socket_nonblocking(ptr);
+ set_socket_nonblocking(server);
}
-static memcached_return_t unix_socket_connect(memcached_server_st *ptr)
+static memcached_return_t unix_socket_connect(memcached_server_st *server)
{
#ifndef WIN32
- WATCHPOINT_ASSERT(ptr->fd == -1);
+ WATCHPOINT_ASSERT(server->fd == INVALID_SOCKET);
- if ((ptr->fd= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ if ((server->fd= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
{
- memcached_set_errno(*ptr, errno, NULL);
+ memcached_set_errno(*server, errno, NULL);
return MEMCACHED_CONNECTION_FAILURE;
}
memset(&servAddr, 0, sizeof (struct sockaddr_un));
servAddr.sun_family= AF_UNIX;
- strncpy(servAddr.sun_path, ptr->hostname, sizeof(servAddr.sun_path)); /* Copy filename */
+ strncpy(servAddr.sun_path, server->hostname, sizeof(servAddr.sun_path)); /* Copy filename */
do {
- if (connect(ptr->fd, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)
+ if (connect(server->fd, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)
{
switch (errno)
{
default:
WATCHPOINT_ERRNO(errno);
- memcached_set_errno(*ptr, errno, MEMCACHED_AT);
+ memcached_set_errno(*server, errno, MEMCACHED_AT);
return MEMCACHED_CONNECTION_FAILURE;
}
}
} while (0);
- ptr->state= MEMCACHED_SERVER_STATE_CONNECTED;
+ server->state= MEMCACHED_SERVER_STATE_CONNECTED;
- WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
+ WATCHPOINT_ASSERT(server->fd != INVALID_SOCKET);
return MEMCACHED_SUCCESS;
#else
- (void)ptr;
+ (void)server;
return MEMCACHED_NOT_SUPPORTED;
#endif
}
-static memcached_return_t network_connect(memcached_server_st *ptr)
+static memcached_return_t network_connect(memcached_server_st *server)
{
bool timeout_error_occured= false;
- WATCHPOINT_ASSERT(ptr->fd == INVALID_SOCKET);
- WATCHPOINT_ASSERT(ptr->cursor_active == 0);
+ WATCHPOINT_ASSERT(server->fd == INVALID_SOCKET);
+ WATCHPOINT_ASSERT(server->cursor_active == 0);
- if (not ptr->address_info)
+ if (server->address_info == NULL or server->address_info_next == NULL)
{
- WATCHPOINT_ASSERT(ptr->state == MEMCACHED_SERVER_STATE_NEW);
+ WATCHPOINT_ASSERT(server->state == MEMCACHED_SERVER_STATE_NEW);
memcached_return_t rc;
uint32_t counter= 5;
while (--counter)
{
- if ((rc= set_hostinfo(ptr)) != MEMCACHED_TIMEOUT)
+ if ((rc= set_hostinfo(server)) != MEMCACHED_TIMEOUT)
{
break;
}
}
if (memcached_failed(rc))
+ {
return rc;
+ }
}
/* Create the socket */
- while (ptr->address_info_next && ptr->fd == INVALID_SOCKET)
+ while (server->address_info_next and server->fd == INVALID_SOCKET)
{
/* Memcache server does not support IPV6 in udp mode, so skip if not ipv4 */
- if (ptr->type == MEMCACHED_CONNECTION_UDP && ptr->address_info_next->ai_family != AF_INET)
+ if (server->type == MEMCACHED_CONNECTION_UDP && server->address_info_next->ai_family != AF_INET)
{
- ptr->address_info_next= ptr->address_info_next->ai_next;
+ server->address_info_next= server->address_info_next->ai_next;
continue;
}
- if ((ptr->fd= socket(ptr->address_info_next->ai_family,
- ptr->address_info_next->ai_socktype,
- ptr->address_info_next->ai_protocol)) < 0)
+ if ((server->fd= socket(server->address_info_next->ai_family,
+ server->address_info_next->ai_socktype,
+ server->address_info_next->ai_protocol)) < 0)
{
- return memcached_set_errno(*ptr, get_socket_errno(), NULL);
+ return memcached_set_errno(*server, get_socket_errno(), NULL);
}
- set_socket_options(ptr);
+ set_socket_options(server);
/* connect to server */
- if ((connect(ptr->fd, ptr->address_info_next->ai_addr, ptr->address_info_next->ai_addrlen) != SOCKET_ERROR))
+ if ((connect(server->fd, server->address_info_next->ai_addr, server->address_info_next->ai_addrlen) != SOCKET_ERROR))
{
- ptr->state= MEMCACHED_SERVER_STATE_CONNECTED;
+ server->state= MEMCACHED_SERVER_STATE_CONNECTED;
return MEMCACHED_SUCCESS;
}
case EINPROGRESS: // nonblocking mode - first return
case EALREADY: // nonblocking mode - subsequent returns
{
- ptr->state= MEMCACHED_SERVER_STATE_IN_PROGRESS;
- memcached_return_t rc= connect_poll(ptr);
+ server->state= MEMCACHED_SERVER_STATE_IN_PROGRESS;
+ memcached_return_t rc= connect_poll(server);
if (memcached_success(rc))
{
- ptr->state= MEMCACHED_SERVER_STATE_CONNECTED;
+ server->state= MEMCACHED_SERVER_STATE_CONNECTED;
return MEMCACHED_SUCCESS;
}
break;
case EINTR: // Special case, we retry ai_addr
- WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
- (void)closesocket(ptr->fd);
- ptr->fd= INVALID_SOCKET;
+ WATCHPOINT_ASSERT(server->fd != INVALID_SOCKET);
+ (void)closesocket(server->fd);
+ server->fd= INVALID_SOCKET;
continue;
default:
break;
}
- WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
- (void)closesocket(ptr->fd);
- ptr->fd= INVALID_SOCKET;
- ptr->address_info_next= ptr->address_info_next->ai_next;
+ WATCHPOINT_ASSERT(server->fd != INVALID_SOCKET);
+ (void)closesocket(server->fd);
+ server->fd= INVALID_SOCKET;
+ server->address_info_next= server->address_info_next->ai_next;
}
- WATCHPOINT_ASSERT(ptr->fd == INVALID_SOCKET);
+ WATCHPOINT_ASSERT(server->fd == INVALID_SOCKET);
if (timeout_error_occured)
{
- if (ptr->fd != INVALID_SOCKET)
+ if (server->fd != INVALID_SOCKET)
{
- (void)closesocket(ptr->fd);
- ptr->fd= INVALID_SOCKET;
+ (void)closesocket(server->fd);
+ server->fd= INVALID_SOCKET;
}
}
WATCHPOINT_STRING("Never got a good file descriptor");
- /* Failed to connect. schedule next retry */
- if (ptr->root->retry_timeout)
- {
- struct timeval next_time;
- if (gettimeofday(&next_time, NULL) == 0)
- {
- ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout;
- }
- }
-
- if (memcached_has_current_error(*ptr))
+ if (memcached_has_current_error(*server))
{
- return memcached_server_error_return(ptr);
+ return memcached_server_error_return(server);
}
- if (timeout_error_occured and ptr->state < MEMCACHED_SERVER_STATE_IN_PROGRESS)
+ if (timeout_error_occured and server->state < MEMCACHED_SERVER_STATE_IN_PROGRESS)
{
- return memcached_set_error(*ptr, MEMCACHED_TIMEOUT, MEMCACHED_AT);
+ return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT);
}
- return memcached_set_error(*ptr, MEMCACHED_CONNECTION_FAILURE, MEMCACHED_AT); /* The last error should be from connect() */
+ return memcached_set_error(*server, MEMCACHED_CONNECTION_FAILURE, MEMCACHED_AT); /* The last error should be from connect() */
}
-void set_last_disconnected_host(memcached_server_write_instance_st self)
-{
- // const_cast
- memcached_st *root= (memcached_st *)self->root;
- memcached_server_free(root->last_disconnected_server);
- root->last_disconnected_server= memcached_server_clone(NULL, self);
-}
+/*
+ backoff_handling()
-memcached_return_t memcached_connect(memcached_server_write_instance_st ptr)
+ Based on time/failure count fail the connect without trying. This prevents waiting in a state where
+ we get caught spending cycles just waiting.
+*/
+static memcached_return_t backoff_handling(memcached_server_write_instance_st server, bool& in_timeout)
{
- memcached_return_t rc= MEMCACHED_NO_SERVERS;
+ /*
+ If we hit server_failure_limit then something is completely wrong about the server.
+
+ 1) If autoeject is enabled we do that.
+ 2) If not? We go into timeout again, there is much else to do :(
+ */
+ if (server->server_failure_counter >= server->root->server_failure_limit)
+ {
+ /*
+ We just auto_eject if we hit this point
+ */
+ if (_is_auto_eject_host(server->root))
+ {
+ set_last_disconnected_host(server);
+ run_distribution((memcached_st *)server->root);
- if (ptr->fd != INVALID_SOCKET)
- {
- return MEMCACHED_SUCCESS;
- }
+ return memcached_set_error(*server, MEMCACHED_SERVER_MARKED_DEAD, MEMCACHED_AT);
+ }
- LIBMEMCACHED_MEMCACHED_CONNECT_START();
+ server->state= MEMCACHED_SERVER_STATE_IN_TIMEOUT;
+
+ // Sanity check/setting
+ if (server->next_retry == 0)
+ {
+ server->next_retry= 1;
+ }
+ }
- /* both retry_timeout and server_failure_limit must be set in order to delay retrying a server on error. */
- WATCHPOINT_ASSERT(ptr->root);
- if (ptr->root->retry_timeout && ptr->next_retry)
+ if (server->state == MEMCACHED_SERVER_STATE_IN_TIMEOUT)
{
struct timeval curr_time;
+ bool _gettime_success= (gettimeofday(&curr_time, NULL) == 0);
- gettimeofday(&curr_time, NULL);
-
- // We should optimize this to remove the allocation if the server was
- // the last server to die
- if (ptr->next_retry > curr_time.tv_sec)
+ /*
+ If next_retry is less then our current time, then we reset and try everything again.
+ */
+ if (_gettime_success and server->next_retry < curr_time.tv_sec)
{
- set_last_disconnected_host(ptr);
-
- return memcached_set_error(*ptr, MEMCACHED_SERVER_MARKED_DEAD, MEMCACHED_AT);
+ server->state= MEMCACHED_SERVER_STATE_NEW;
}
+ else
+ {
+ return memcached_set_error(*server, MEMCACHED_SERVER_TEMPORARILY_DISABLED, MEMCACHED_AT);
+ }
+
+ in_timeout= true;
}
- // If we are over the counter failure, we just fail. Reject host only
- // works if you have a set number of failures.
- if (ptr->root->server_failure_limit && ptr->server_failure_counter >= ptr->root->server_failure_limit)
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return_t memcached_connect(memcached_server_write_instance_st server)
+{
+ if (server->fd != INVALID_SOCKET)
{
- set_last_disconnected_host(ptr);
+ return MEMCACHED_SUCCESS;
+ }
- // @todo fix this by fixing behavior to no longer make use of
- // memcached_st
- if (_is_auto_eject_host(ptr->root))
- {
- run_distribution((memcached_st *)ptr->root);
- }
+ LIBMEMCACHED_MEMCACHED_CONNECT_START();
- return memcached_set_error(*ptr, MEMCACHED_SERVER_MARKED_DEAD, MEMCACHED_AT);
+ bool in_timeout= false;
+ memcached_return_t rc;
+ if (memcached_failed(rc= backoff_handling(server, in_timeout)))
+ {
+ set_last_disconnected_host(server);
+ return rc;
}
/* We need to clean up the multi startup piece */
- switch (ptr->type)
+ switch (server->type)
{
case MEMCACHED_CONNECTION_UDP:
case MEMCACHED_CONNECTION_TCP:
- rc= network_connect(ptr);
+ rc= network_connect(server);
+
if (LIBMEMCACHED_WITH_SASL_SUPPORT)
{
- if (ptr->fd != INVALID_SOCKET and ptr->root->sasl.callbacks)
+ if (server->fd != INVALID_SOCKET and server->root->sasl.callbacks)
{
- rc= memcached_sasl_authenticate_connection(ptr);
- if (memcached_failed(rc) and ptr->fd != INVALID_SOCKET)
+ rc= memcached_sasl_authenticate_connection(server);
+ if (memcached_failed(rc) and server->fd != INVALID_SOCKET)
{
- WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
- (void)closesocket(ptr->fd);
- ptr->fd= INVALID_SOCKET;
+ WATCHPOINT_ASSERT(server->fd != INVALID_SOCKET);
+ (void)closesocket(server->fd);
+ server->fd= INVALID_SOCKET;
}
}
}
break;
case MEMCACHED_CONNECTION_UNIX_SOCKET:
- rc= unix_socket_connect(ptr);
+ rc= unix_socket_connect(server);
break;
}
if (memcached_success(rc))
{
- ptr->server_failure_counter= 0;
- ptr->next_retry= 0;
+ memcached_mark_server_as_clean(server);
+ return rc;
}
- else if (memcached_has_current_error(*ptr))
+
+ set_last_disconnected_host(server);
+ if (memcached_has_current_error(*server))
{
- ptr->server_failure_counter++;
- set_last_disconnected_host(ptr);
+ memcached_mark_server_for_timeout(server);
+ assert(memcached_failed(memcached_server_error_return(server)));
}
else
{
- memcached_set_error(*ptr, rc, MEMCACHED_AT);
- ptr->server_failure_counter++;
- set_last_disconnected_host(ptr);
+ memcached_set_error(*server, rc, MEMCACHED_AT);
+ memcached_mark_server_for_timeout(server);
}
LIBMEMCACHED_MEMCACHED_CONNECT_END();
+ if (in_timeout)
+ {
+ return memcached_set_error(*server, MEMCACHED_SERVER_TEMPORARILY_DISABLED, MEMCACHED_AT);
+ }
+
return rc;
}
#define MEMCACHED_EXPIRATION_NOT_ADD 0xffffffffU
#define MEMCACHED_VERSION_STRING_LENGTH 24
#define MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH 20
+#define MEMCACHED_SERVER_FAILURE_LIMIT 5
+#define MEMCACHED_SERVER_FAILURE_RETRY_TIMEOUT 2
enum memcached_server_distribution_t {
#include <libmemcached/csl/symbol.h>
#include <libmemcached/csl/scanner.h>
+#ifndef __INTEL_COMPILER
#pragma GCC diagnostic ignored "-Wold-style-cast"
+#endif
int conf_lex(YYSTYPE* lvalp, void* scanner);
/* Line 189 of yacc.c */
-#line 118 "libmemcached/csl/parser.cc"
+#line 120 "libmemcached/csl/parser.cc"
/* Enabling traces. */
#ifndef YYDEBUG
/* Line 264 of yacc.c */
-#line 230 "libmemcached/csl/parser.cc"
+#line 232 "libmemcached/csl/parser.cc"
#ifdef short
# undef short
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 170, 170, 171, 175, 177, 179, 181, 186, 191,
- 195, 199, 210, 218, 226, 233, 237, 241, 245, 249,
- 256, 263, 274, 281, 288, 295, 301, 305, 309, 313,
- 317, 321, 325, 329, 333, 337, 341, 345, 352, 356,
- 360, 364, 368, 372, 376, 380, 384, 388, 392, 396,
- 403, 404, 409, 410, 415, 419, 423, 427, 431, 435,
- 439, 443, 447, 454, 458, 465, 469, 473
+ 0, 172, 172, 173, 177, 179, 181, 183, 188, 193,
+ 197, 201, 212, 220, 228, 235, 239, 243, 247, 251,
+ 258, 265, 276, 283, 290, 297, 303, 307, 311, 315,
+ 319, 323, 327, 331, 335, 339, 343, 347, 354, 358,
+ 362, 366, 370, 374, 378, 382, 386, 390, 394, 398,
+ 405, 406, 411, 412, 417, 421, 425, 429, 433, 437,
+ 441, 445, 449, 456, 460, 467, 471, 475
};
#endif
case 4:
/* Line 1464 of yacc.c */
-#line 176 "libmemcached/csl/parser.yy"
+#line 178 "libmemcached/csl/parser.yy"
{ ;}
break;
case 5:
/* Line 1464 of yacc.c */
-#line 178 "libmemcached/csl/parser.yy"
+#line 180 "libmemcached/csl/parser.yy"
{ ;}
break;
case 6:
/* Line 1464 of yacc.c */
-#line 180 "libmemcached/csl/parser.yy"
+#line 182 "libmemcached/csl/parser.yy"
{ ;}
break;
case 7:
/* Line 1464 of yacc.c */
-#line 182 "libmemcached/csl/parser.yy"
+#line 184 "libmemcached/csl/parser.yy"
{
context->set_end();
YYACCEPT;
case 8:
/* Line 1464 of yacc.c */
-#line 187 "libmemcached/csl/parser.yy"
+#line 189 "libmemcached/csl/parser.yy"
{
context->rc= MEMCACHED_PARSE_USER_ERROR;
parser_abort(context, NULL);
case 9:
/* Line 1464 of yacc.c */
-#line 192 "libmemcached/csl/parser.yy"
+#line 194 "libmemcached/csl/parser.yy"
{
memcached_reset(context->memc);
;}
case 10:
/* Line 1464 of yacc.c */
-#line 196 "libmemcached/csl/parser.yy"
+#line 198 "libmemcached/csl/parser.yy"
{
yydebug= 1;
;}
case 11:
/* Line 1464 of yacc.c */
-#line 200 "libmemcached/csl/parser.yy"
+#line 202 "libmemcached/csl/parser.yy"
{
if ((context->rc= memcached_parse_configure_file(*context->memc, (yyvsp[(3) - (3)].string).c_str, (yyvsp[(3) - (3)].string).size)) != MEMCACHED_SUCCESS)
{
case 12:
/* Line 1464 of yacc.c */
-#line 211 "libmemcached/csl/parser.yy"
+#line 213 "libmemcached/csl/parser.yy"
{
if (memcached_failed(context->rc= memcached_server_add_with_weight(context->memc, (yyvsp[(2) - (4)].server).c_str, (yyvsp[(3) - (4)].number), (yyvsp[(4) - (4)].number))))
{
case 13:
/* Line 1464 of yacc.c */
-#line 219 "libmemcached/csl/parser.yy"
+#line 221 "libmemcached/csl/parser.yy"
{
if (memcached_failed(context->rc= memcached_server_add_with_weight(context->memc, (yyvsp[(2) - (4)].server).c_str, (yyvsp[(3) - (4)].number), (yyvsp[(4) - (4)].number))))
{
case 14:
/* Line 1464 of yacc.c */
-#line 227 "libmemcached/csl/parser.yy"
+#line 229 "libmemcached/csl/parser.yy"
{
if (memcached_failed(context->rc= memcached_server_add_unix_socket_with_weight(context->memc, (yyvsp[(2) - (3)].string).c_str, (yyvsp[(3) - (3)].number))))
{
case 15:
/* Line 1464 of yacc.c */
-#line 234 "libmemcached/csl/parser.yy"
+#line 236 "libmemcached/csl/parser.yy"
{
memcached_set_configuration_file(context->memc, (yyvsp[(2) - (2)].string).c_str, (yyvsp[(2) - (2)].string).size);
;}
case 16:
/* Line 1464 of yacc.c */
-#line 238 "libmemcached/csl/parser.yy"
+#line 240 "libmemcached/csl/parser.yy"
{
context->memc->configure.initial_pool_size= (yyvsp[(2) - (2)].number);
;}
case 17:
/* Line 1464 of yacc.c */
-#line 242 "libmemcached/csl/parser.yy"
+#line 244 "libmemcached/csl/parser.yy"
{
context->memc->configure.max_pool_size= (yyvsp[(2) - (2)].number);
;}
case 19:
/* Line 1464 of yacc.c */
-#line 250 "libmemcached/csl/parser.yy"
+#line 252 "libmemcached/csl/parser.yy"
{
if ((context->rc= memcached_set_namespace(context->memc, (yyvsp[(2) - (2)].string).c_str, (yyvsp[(2) - (2)].string).size)) != MEMCACHED_SUCCESS)
{
case 20:
/* Line 1464 of yacc.c */
-#line 257 "libmemcached/csl/parser.yy"
+#line 259 "libmemcached/csl/parser.yy"
{
if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, (yyvsp[(2) - (2)].distribution))) != MEMCACHED_SUCCESS)
{
case 21:
/* Line 1464 of yacc.c */
-#line 264 "libmemcached/csl/parser.yy"
+#line 266 "libmemcached/csl/parser.yy"
{
if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, (yyvsp[(2) - (4)].distribution))) != MEMCACHED_SUCCESS)
{
case 22:
/* Line 1464 of yacc.c */
-#line 275 "libmemcached/csl/parser.yy"
+#line 277 "libmemcached/csl/parser.yy"
{
if ((context->rc= memcached_behavior_set(context->memc, MEMCACHED_BEHAVIOR_HASH, (yyvsp[(2) - (2)].hash))) != MEMCACHED_SUCCESS)
{
case 23:
/* Line 1464 of yacc.c */
-#line 282 "libmemcached/csl/parser.yy"
+#line 284 "libmemcached/csl/parser.yy"
{
if ((context->rc= memcached_behavior_set(context->memc, (yyvsp[(1) - (2)].behavior), (yyvsp[(2) - (2)].number))) != MEMCACHED_SUCCESS)
{
case 24:
/* Line 1464 of yacc.c */
-#line 289 "libmemcached/csl/parser.yy"
+#line 291 "libmemcached/csl/parser.yy"
{
if ((context->rc= memcached_behavior_set(context->memc, (yyvsp[(1) - (1)].behavior), true)) != MEMCACHED_SUCCESS)
{
case 25:
/* Line 1464 of yacc.c */
-#line 296 "libmemcached/csl/parser.yy"
+#line 298 "libmemcached/csl/parser.yy"
{
;}
break;
case 26:
/* Line 1464 of yacc.c */
-#line 302 "libmemcached/csl/parser.yy"
+#line 304 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS;
;}
case 27:
/* Line 1464 of yacc.c */
-#line 306 "libmemcached/csl/parser.yy"
+#line 308 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT;
;}
case 28:
/* Line 1464 of yacc.c */
-#line 310 "libmemcached/csl/parser.yy"
+#line 312 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK;
;}
case 29:
/* Line 1464 of yacc.c */
-#line 314 "libmemcached/csl/parser.yy"
+#line 316 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK;
;}
case 30:
/* Line 1464 of yacc.c */
-#line 318 "libmemcached/csl/parser.yy"
+#line 320 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH;
;}
case 31:
/* Line 1464 of yacc.c */
-#line 322 "libmemcached/csl/parser.yy"
+#line 324 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS;
;}
case 32:
/* Line 1464 of yacc.c */
-#line 326 "libmemcached/csl/parser.yy"
+#line 328 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_POLL_TIMEOUT;
;}
case 33:
/* Line 1464 of yacc.c */
-#line 330 "libmemcached/csl/parser.yy"
+#line 332 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_RCV_TIMEOUT;
;}
case 34:
/* Line 1464 of yacc.c */
-#line 334 "libmemcached/csl/parser.yy"
+#line 336 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_RETRY_TIMEOUT;
;}
case 35:
/* Line 1464 of yacc.c */
-#line 338 "libmemcached/csl/parser.yy"
+#line 340 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_SND_TIMEOUT;
;}
case 36:
/* Line 1464 of yacc.c */
-#line 342 "libmemcached/csl/parser.yy"
+#line 344 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE;
;}
case 37:
/* Line 1464 of yacc.c */
-#line 346 "libmemcached/csl/parser.yy"
+#line 348 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE;
;}
case 38:
/* Line 1464 of yacc.c */
-#line 353 "libmemcached/csl/parser.yy"
+#line 355 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_BINARY_PROTOCOL;
;}
case 39:
/* Line 1464 of yacc.c */
-#line 357 "libmemcached/csl/parser.yy"
+#line 359 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_BUFFER_REQUESTS;
;}
case 40:
/* Line 1464 of yacc.c */
-#line 361 "libmemcached/csl/parser.yy"
+#line 363 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY;
;}
case 41:
/* Line 1464 of yacc.c */
-#line 365 "libmemcached/csl/parser.yy"
+#line 367 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_NOREPLY;
;}
case 42:
/* Line 1464 of yacc.c */
-#line 369 "libmemcached/csl/parser.yy"
+#line 371 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ;
;}
case 43:
/* Line 1464 of yacc.c */
-#line 373 "libmemcached/csl/parser.yy"
+#line 375 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_SORT_HOSTS;
;}
case 44:
/* Line 1464 of yacc.c */
-#line 377 "libmemcached/csl/parser.yy"
+#line 379 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_SUPPORT_CAS;
;}
case 45:
/* Line 1464 of yacc.c */
-#line 381 "libmemcached/csl/parser.yy"
+#line 383 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_TCP_NODELAY;
;}
case 46:
/* Line 1464 of yacc.c */
-#line 385 "libmemcached/csl/parser.yy"
+#line 387 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_TCP_KEEPALIVE;
;}
case 47:
/* Line 1464 of yacc.c */
-#line 389 "libmemcached/csl/parser.yy"
+#line 391 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_TCP_KEEPIDLE;
;}
case 48:
/* Line 1464 of yacc.c */
-#line 393 "libmemcached/csl/parser.yy"
+#line 395 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_USE_UDP;
;}
case 49:
/* Line 1464 of yacc.c */
-#line 397 "libmemcached/csl/parser.yy"
+#line 399 "libmemcached/csl/parser.yy"
{
(yyval.behavior)= MEMCACHED_BEHAVIOR_VERIFY_KEY;
;}
case 50:
/* Line 1464 of yacc.c */
-#line 403 "libmemcached/csl/parser.yy"
+#line 405 "libmemcached/csl/parser.yy"
{ (yyval.number)= MEMCACHED_DEFAULT_PORT;;}
break;
case 51:
/* Line 1464 of yacc.c */
-#line 405 "libmemcached/csl/parser.yy"
+#line 407 "libmemcached/csl/parser.yy"
{ ;}
break;
case 52:
/* Line 1464 of yacc.c */
-#line 409 "libmemcached/csl/parser.yy"
+#line 411 "libmemcached/csl/parser.yy"
{ (yyval.number)= 1; ;}
break;
case 53:
/* Line 1464 of yacc.c */
-#line 411 "libmemcached/csl/parser.yy"
+#line 413 "libmemcached/csl/parser.yy"
{ ;}
break;
case 54:
/* Line 1464 of yacc.c */
-#line 416 "libmemcached/csl/parser.yy"
+#line 418 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_MD5;
;}
case 55:
/* Line 1464 of yacc.c */
-#line 420 "libmemcached/csl/parser.yy"
+#line 422 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_CRC;
;}
case 56:
/* Line 1464 of yacc.c */
-#line 424 "libmemcached/csl/parser.yy"
+#line 426 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_FNV1_64;
;}
case 57:
/* Line 1464 of yacc.c */
-#line 428 "libmemcached/csl/parser.yy"
+#line 430 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_FNV1A_64;
;}
case 58:
/* Line 1464 of yacc.c */
-#line 432 "libmemcached/csl/parser.yy"
+#line 434 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_FNV1_32;
;}
case 59:
/* Line 1464 of yacc.c */
-#line 436 "libmemcached/csl/parser.yy"
+#line 438 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_FNV1A_32;
;}
case 60:
/* Line 1464 of yacc.c */
-#line 440 "libmemcached/csl/parser.yy"
+#line 442 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_HSIEH;
;}
case 61:
/* Line 1464 of yacc.c */
-#line 444 "libmemcached/csl/parser.yy"
+#line 446 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_MURMUR;
;}
case 62:
/* Line 1464 of yacc.c */
-#line 448 "libmemcached/csl/parser.yy"
+#line 450 "libmemcached/csl/parser.yy"
{
(yyval.hash)= MEMCACHED_HASH_JENKINS;
;}
case 63:
/* Line 1464 of yacc.c */
-#line 455 "libmemcached/csl/parser.yy"
+#line 457 "libmemcached/csl/parser.yy"
{
(yyval.string)= (yyvsp[(1) - (1)].string);
;}
case 64:
/* Line 1464 of yacc.c */
-#line 459 "libmemcached/csl/parser.yy"
+#line 461 "libmemcached/csl/parser.yy"
{
(yyval.string)= (yyvsp[(1) - (1)].string);
;}
case 65:
/* Line 1464 of yacc.c */
-#line 466 "libmemcached/csl/parser.yy"
+#line 468 "libmemcached/csl/parser.yy"
{
(yyval.distribution)= MEMCACHED_DISTRIBUTION_CONSISTENT;
;}
case 66:
/* Line 1464 of yacc.c */
-#line 470 "libmemcached/csl/parser.yy"
+#line 472 "libmemcached/csl/parser.yy"
{
(yyval.distribution)= MEMCACHED_DISTRIBUTION_MODULA;
;}
case 67:
/* Line 1464 of yacc.c */
-#line 474 "libmemcached/csl/parser.yy"
+#line 476 "libmemcached/csl/parser.yy"
{
(yyval.distribution)= MEMCACHED_DISTRIBUTION_RANDOM;
;}
/* Line 1464 of yacc.c */
-#line 2127 "libmemcached/csl/parser.cc"
+#line 2129 "libmemcached/csl/parser.cc"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
/* Line 1684 of yacc.c */
-#line 479 "libmemcached/csl/parser.yy"
+#line 481 "libmemcached/csl/parser.yy"
void Context::start()
#include <libmemcached/csl/parser.h>
#include <libmemcached/csl/symbol.h>
+#ifndef __INTEL_COMPILER
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
#define YY_EXTRA_TYPE Context*
-#line 19 "libmemcached/csl/scanner.cc"
+#line 21 "libmemcached/csl/scanner.cc"
#define YY_INT_ALIGNED short int
static yyconst flex_int16_t yy_rule_linenum[65] =
{ 0,
- 77, 79, 81, 83, 85, 88, 92, 94, 96, 97,
- 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
- 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
- 118, 119, 120, 121, 122, 123, 125, 126, 128, 130,
- 131, 132, 133, 134, 135, 137, 138, 141, 146, 147,
- 148, 150, 151, 152, 153, 154, 155, 156, 157, 158,
- 160, 169, 187, 194
+ 79, 81, 83, 85, 87, 90, 94, 96, 98, 99,
+ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 127, 128, 130, 132,
+ 133, 134, 135, 136, 137, 139, 140, 143, 148, 149,
+ 150, 152, 153, 154, 155, 156, 157, 158, 159, 160,
+ 162, 171, 189, 196
} ;
/* The intent behind this definition is that it'll catch
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#line 38 "libmemcached/csl/scanner.l"
+#line 40 "libmemcached/csl/scanner.l"
#include <cstdlib>
#include <cstring>
#define YY_INPUT(buffer, result, max_size) get_lex_chars(buffer, result, max_size, PARAM)
-#line 1154 "libmemcached/csl/scanner.cc"
+#line 1156 "libmemcached/csl/scanner.cc"
#define INITIAL 0
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* %% [7.0] user's declarations go here */
-#line 74 "libmemcached/csl/scanner.l"
+#line 76 "libmemcached/csl/scanner.l"
-#line 1461 "libmemcached/csl/scanner.cc"
+#line 1463 "libmemcached/csl/scanner.cc"
yylval = yylval_param;
case 1:
YY_RULE_SETUP
-#line 77 "libmemcached/csl/scanner.l"
+#line 79 "libmemcached/csl/scanner.l"
{ return yytext[0];}
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 79 "libmemcached/csl/scanner.l"
+#line 81 "libmemcached/csl/scanner.l"
{ yylval->number= atoi(yytext); return (NUMBER); }
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 81 "libmemcached/csl/scanner.l"
+#line 83 "libmemcached/csl/scanner.l"
{ yylval->number= atoi(yytext +1); return PORT; }
YY_BREAK
case 4:
YY_RULE_SETUP
-#line 83 "libmemcached/csl/scanner.l"
+#line 85 "libmemcached/csl/scanner.l"
{ yylval->number= atoi(yytext +2); return WEIGHT_START; }
YY_BREAK
case 5:
/* rule 5 can match eol */
YY_RULE_SETUP
-#line 85 "libmemcached/csl/scanner.l"
+#line 87 "libmemcached/csl/scanner.l"
; /* skip whitespace */
YY_BREAK
case 6:
yyg->yy_c_buf_p = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up yytext again */
YY_RULE_SETUP
-#line 88 "libmemcached/csl/scanner.l"
+#line 90 "libmemcached/csl/scanner.l"
{
return COMMENT;
}
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 92 "libmemcached/csl/scanner.l"
+#line 94 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; yyextra->set_server(); return yyextra->previous_token= SERVER; }
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 94 "libmemcached/csl/scanner.l"
+#line 96 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= SOCKET; }
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 96 "libmemcached/csl/scanner.l"
+#line 98 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= BINARY_PROTOCOL; }
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 97 "libmemcached/csl/scanner.l"
+#line 99 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= BUFFER_REQUESTS; }
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 98 "libmemcached/csl/scanner.l"
+#line 100 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= CONFIGURE_FILE; }
YY_BREAK
case 12:
YY_RULE_SETUP
-#line 99 "libmemcached/csl/scanner.l"
+#line 101 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= CONNECT_TIMEOUT; }
YY_BREAK
case 13:
YY_RULE_SETUP
-#line 100 "libmemcached/csl/scanner.l"
+#line 102 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= DISTRIBUTION; }
YY_BREAK
case 14:
YY_RULE_SETUP
-#line 101 "libmemcached/csl/scanner.l"
+#line 103 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= HASH_WITH_NAMESPACE; }
YY_BREAK
case 15:
YY_RULE_SETUP
-#line 102 "libmemcached/csl/scanner.l"
+#line 104 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= HASH; }
YY_BREAK
case 16:
YY_RULE_SETUP
-#line 103 "libmemcached/csl/scanner.l"
+#line 105 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= IO_BYTES_WATERMARK; }
YY_BREAK
case 17:
YY_RULE_SETUP
-#line 104 "libmemcached/csl/scanner.l"
+#line 106 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= IO_KEY_PREFETCH; }
YY_BREAK
case 18:
YY_RULE_SETUP
-#line 105 "libmemcached/csl/scanner.l"
+#line 107 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= IO_MSG_WATERMARK; }
YY_BREAK
case 19:
YY_RULE_SETUP
-#line 106 "libmemcached/csl/scanner.l"
+#line 108 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= NOREPLY; }
YY_BREAK
case 20:
YY_RULE_SETUP
-#line 107 "libmemcached/csl/scanner.l"
+#line 109 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= NUMBER_OF_REPLICAS; }
YY_BREAK
case 21:
YY_RULE_SETUP
-#line 108 "libmemcached/csl/scanner.l"
+#line 110 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= POLL_TIMEOUT; }
YY_BREAK
case 22:
YY_RULE_SETUP
-#line 109 "libmemcached/csl/scanner.l"
+#line 111 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= RANDOMIZE_REPLICA_READ; }
YY_BREAK
case 23:
YY_RULE_SETUP
-#line 110 "libmemcached/csl/scanner.l"
+#line 112 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= RCV_TIMEOUT; }
YY_BREAK
case 24:
YY_RULE_SETUP
-#line 111 "libmemcached/csl/scanner.l"
+#line 113 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= REMOVE_FAILED_SERVERS; }
YY_BREAK
case 25:
YY_RULE_SETUP
-#line 112 "libmemcached/csl/scanner.l"
+#line 114 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= RETRY_TIMEOUT; }
YY_BREAK
case 26:
YY_RULE_SETUP
-#line 113 "libmemcached/csl/scanner.l"
+#line 115 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= SND_TIMEOUT; }
YY_BREAK
case 27:
YY_RULE_SETUP
-#line 114 "libmemcached/csl/scanner.l"
+#line 116 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= SOCKET_RECV_SIZE; }
YY_BREAK
case 28:
YY_RULE_SETUP
-#line 115 "libmemcached/csl/scanner.l"
+#line 117 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= SOCKET_SEND_SIZE; }
YY_BREAK
case 29:
YY_RULE_SETUP
-#line 116 "libmemcached/csl/scanner.l"
+#line 118 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= SORT_HOSTS; }
YY_BREAK
case 30:
YY_RULE_SETUP
-#line 117 "libmemcached/csl/scanner.l"
+#line 119 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= SUPPORT_CAS; }
YY_BREAK
case 31:
YY_RULE_SETUP
-#line 118 "libmemcached/csl/scanner.l"
+#line 120 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= _TCP_KEEPALIVE; }
YY_BREAK
case 32:
YY_RULE_SETUP
-#line 119 "libmemcached/csl/scanner.l"
+#line 121 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= _TCP_KEEPIDLE; }
YY_BREAK
case 33:
YY_RULE_SETUP
-#line 120 "libmemcached/csl/scanner.l"
+#line 122 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= _TCP_NODELAY; }
YY_BREAK
case 34:
YY_RULE_SETUP
-#line 121 "libmemcached/csl/scanner.l"
+#line 123 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= USE_UDP; }
YY_BREAK
case 35:
YY_RULE_SETUP
-#line 122 "libmemcached/csl/scanner.l"
+#line 124 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= USER_DATA; }
YY_BREAK
case 36:
YY_RULE_SETUP
-#line 123 "libmemcached/csl/scanner.l"
+#line 125 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= VERIFY_KEY; }
YY_BREAK
case 37:
YY_RULE_SETUP
-#line 125 "libmemcached/csl/scanner.l"
+#line 127 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= POOL_MIN; }
YY_BREAK
case 38:
YY_RULE_SETUP
-#line 126 "libmemcached/csl/scanner.l"
+#line 128 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= POOL_MAX; }
YY_BREAK
case 39:
YY_RULE_SETUP
-#line 128 "libmemcached/csl/scanner.l"
+#line 130 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= NAMESPACE; }
YY_BREAK
case 40:
YY_RULE_SETUP
-#line 130 "libmemcached/csl/scanner.l"
+#line 132 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= INCLUDE; }
YY_BREAK
case 41:
YY_RULE_SETUP
-#line 131 "libmemcached/csl/scanner.l"
+#line 133 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= RESET; }
YY_BREAK
case 42:
YY_RULE_SETUP
-#line 132 "libmemcached/csl/scanner.l"
+#line 134 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= PARSER_DEBUG; }
YY_BREAK
case 43:
YY_RULE_SETUP
-#line 133 "libmemcached/csl/scanner.l"
+#line 135 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= SERVERS; }
YY_BREAK
case 44:
YY_RULE_SETUP
-#line 134 "libmemcached/csl/scanner.l"
+#line 136 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= END; }
YY_BREAK
case 45:
YY_RULE_SETUP
-#line 135 "libmemcached/csl/scanner.l"
+#line 137 "libmemcached/csl/scanner.l"
{ yyextra->begin= yytext; return yyextra->previous_token= ERROR; }
YY_BREAK
case 46:
YY_RULE_SETUP
-#line 137 "libmemcached/csl/scanner.l"
+#line 139 "libmemcached/csl/scanner.l"
{ return yyextra->previous_token= TRUE; }
YY_BREAK
case 47:
YY_RULE_SETUP
-#line 138 "libmemcached/csl/scanner.l"
+#line 140 "libmemcached/csl/scanner.l"
{ return yyextra->previous_token= FALSE; }
YY_BREAK
case 48:
YY_RULE_SETUP
-#line 141 "libmemcached/csl/scanner.l"
+#line 143 "libmemcached/csl/scanner.l"
{
yyextra->begin= yytext;
return UNKNOWN_OPTION;
YY_BREAK
case 49:
YY_RULE_SETUP
-#line 146 "libmemcached/csl/scanner.l"
+#line 148 "libmemcached/csl/scanner.l"
{ return CONSISTENT; }
YY_BREAK
case 50:
YY_RULE_SETUP
-#line 147 "libmemcached/csl/scanner.l"
+#line 149 "libmemcached/csl/scanner.l"
{ return MODULA; }
YY_BREAK
case 51:
YY_RULE_SETUP
-#line 148 "libmemcached/csl/scanner.l"
+#line 150 "libmemcached/csl/scanner.l"
{ return RANDOM; }
YY_BREAK
case 52:
YY_RULE_SETUP
-#line 150 "libmemcached/csl/scanner.l"
+#line 152 "libmemcached/csl/scanner.l"
{ return MD5; }
YY_BREAK
case 53:
YY_RULE_SETUP
-#line 151 "libmemcached/csl/scanner.l"
+#line 153 "libmemcached/csl/scanner.l"
{ return CRC; }
YY_BREAK
case 54:
YY_RULE_SETUP
-#line 152 "libmemcached/csl/scanner.l"
+#line 154 "libmemcached/csl/scanner.l"
{ return FNV1_64; }
YY_BREAK
case 55:
YY_RULE_SETUP
-#line 153 "libmemcached/csl/scanner.l"
+#line 155 "libmemcached/csl/scanner.l"
{ return FNV1A_64; }
YY_BREAK
case 56:
YY_RULE_SETUP
-#line 154 "libmemcached/csl/scanner.l"
+#line 156 "libmemcached/csl/scanner.l"
{ return FNV1_32; }
YY_BREAK
case 57:
YY_RULE_SETUP
-#line 155 "libmemcached/csl/scanner.l"
+#line 157 "libmemcached/csl/scanner.l"
{ return FNV1A_32; }
YY_BREAK
case 58:
YY_RULE_SETUP
-#line 156 "libmemcached/csl/scanner.l"
+#line 158 "libmemcached/csl/scanner.l"
{ return HSIEH; }
YY_BREAK
case 59:
YY_RULE_SETUP
-#line 157 "libmemcached/csl/scanner.l"
+#line 159 "libmemcached/csl/scanner.l"
{ return MURMUR; }
YY_BREAK
case 60:
YY_RULE_SETUP
-#line 158 "libmemcached/csl/scanner.l"
+#line 160 "libmemcached/csl/scanner.l"
{ return JENKINS; }
YY_BREAK
case 61:
YY_RULE_SETUP
-#line 160 "libmemcached/csl/scanner.l"
+#line 162 "libmemcached/csl/scanner.l"
{
yylval->server.port= MEMCACHED_DEFAULT_PORT;
yylval->server.weight= 1;
YY_BREAK
case 62:
YY_RULE_SETUP
-#line 169 "libmemcached/csl/scanner.l"
+#line 171 "libmemcached/csl/scanner.l"
{
if (yyextra->is_server())
{
case 63:
/* rule 63 can match eol */
YY_RULE_SETUP
-#line 187 "libmemcached/csl/scanner.l"
+#line 189 "libmemcached/csl/scanner.l"
{
config_get_text(yyscanner)[yyleng -1]= 0;
yylval->string.c_str= yytext +1;
YY_BREAK
case 64:
YY_RULE_SETUP
-#line 194 "libmemcached/csl/scanner.l"
+#line 196 "libmemcached/csl/scanner.l"
{
yyextra->begin= yytext;
return UNKNOWN;
YY_BREAK
case 65:
YY_RULE_SETUP
-#line 199 "libmemcached/csl/scanner.l"
+#line 201 "libmemcached/csl/scanner.l"
ECHO;
YY_BREAK
-#line 1944 "libmemcached/csl/scanner.cc"
+#line 1946 "libmemcached/csl/scanner.cc"
case YY_STATE_EOF(INITIAL):
yyterminate();
/* %ok-for-header */
-#line 199 "libmemcached/csl/scanner.l"
+#line 201 "libmemcached/csl/scanner.l"
#include <libmemcached/csl/parser.h>
#include <libmemcached/csl/symbol.h>
+#ifndef __INTEL_COMPILER
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
#define YY_EXTRA_TYPE Context*
-#line 23 "libmemcached/csl/scanner.h"
+#line 25 "libmemcached/csl/scanner.h"
#define YY_INT_ALIGNED short int
#undef YY_DECL
#endif
-#line 199 "libmemcached/csl/scanner.l"
+#line 201 "libmemcached/csl/scanner.l"
-#line 478 "libmemcached/csl/scanner.h"
+#line 480 "libmemcached/csl/scanner.h"
#undef config_IN_HEADER
#endif /* config_HEADER_H */
{
rc= memcached_connect(instance);
if (memcached_failed(rc))
+ {
continue;
+ }
}
protocol_binary_request_getk request= { }; //= {.bytes= {0}};
server += start;
while (server >= memcached_server_count(ptr))
+ {
server -= memcached_server_count(ptr);
+ }
if (dead_servers[server])
+ {
continue;
+ }
memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server);
if (memcached_server_response_count(instance) == 0)
{
rc= memcached_connect(instance);
+
if (memcached_failed(rc))
{
memcached_io_reset(instance);
{
struct timeval now;
- if (gettimeofday(&now, NULL) == 0 &&
+ if (gettimeofday(&now, NULL) == 0 and
now.tv_sec > ptr->ketama.next_distribution_rebuild)
{
run_distribution(ptr);
#include <sys/time.h>
/* Protoypes (static) */
-static memcached_return_t server_add(memcached_st *ptr, const char *hostname,
- in_port_t port,
- uint32_t weight,
- memcached_connection_t type);
-
static memcached_return_t update_continuum(memcached_st *ptr);
static int compare_servers(const void *p1, const void *p2)
}
else
{
- if (ptr->ketama.next_distribution_rebuild == 0 || list[host_index].next_retry < ptr->ketama.next_distribution_rebuild)
+ if (ptr->ketama.next_distribution_rebuild == 0 or list[host_index].next_retry < ptr->ketama.next_distribution_rebuild)
{
ptr->ketama.next_distribution_rebuild= list[host_index].next_retry;
}
sizeof(memcached_continuum_item_st) * (live_servers + MEMCACHED_CONTINUUM_ADDITION) * points_per_server));
if (new_ptr == 0)
+ {
return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+ }
ptr->ketama.continuum= new_ptr;
ptr->ketama.continuum_count= live_servers + MEMCACHED_CONTINUUM_ADDITION;
{
for (uint32_t host_index = 0; host_index < memcached_server_count(ptr); ++host_index)
{
- if (! is_auto_ejecting || list[host_index].next_retry <= now.tv_sec)
+ if (is_auto_ejecting == false or list[host_index].next_retry <= now.tv_sec)
{
total_weight += list[host_index].weight;
}
for (uint32_t host_index= 0; host_index < memcached_server_count(ptr); ++host_index)
{
- if (is_auto_ejecting && list[host_index].next_retry > now.tv_sec)
+ if (is_auto_ejecting and list[host_index].next_retry > now.tv_sec)
+ {
continue;
+ }
if (is_ketama_weighted)
{
- float pct = (float)list[host_index].weight / (float)total_weight;
+ float pct= (float)list[host_index].weight / (float)total_weight;
pointer_per_server= (uint32_t) ((floorf((float) (pct * MEMCACHED_POINTS_PER_SERVER_KETAMA / 4 * (float)live_servers + 0.0000000001))) * 4);
pointer_per_hash= 4;
-#ifdef DEBUG
- printf("ketama_weighted:%s|%d|%llu|%u\n",
- list[host_index].hostname,
- list[host_index].port,
- (unsigned long long)list[host_index].weight,
- pointer_per_server);
-#endif
+ if (DEBUG)
+ {
+ printf("ketama_weighted:%s|%d|%llu|%u\n",
+ list[host_index].hostname,
+ list[host_index].port,
+ (unsigned long long)list[host_index].weight,
+ pointer_per_server);
+ }
}
return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT,
memcached_literal_param("snprintf(MEMCACHED_DEFAULT_COMMAND_SIZE)"));
}
-#ifdef DEBUG
- printf("update_continuum: key is %s\n", sort_host);
-#endif
+
+ if (DEBUG)
+ {
+ fprintf(stdout, "update_continuum: key is %s\n", sort_host);
+ }
+
if (is_ketama_weighted)
{
for (uint32_t x= 0; x < pointer_per_hash; x++)
ptr->ketama.continuum_points_counter= pointer_counter;
qsort(ptr->ketama.continuum, ptr->ketama.continuum_points_counter, sizeof(memcached_continuum_item_st), continuum_item_cmp);
-#ifdef DEBUG
- for (uint32_t pointer_index= 0; memcached_server_count(ptr) && pointer_index < ((live_servers * MEMCACHED_POINTS_PER_SERVER) - 1); pointer_index++)
+ if (DEBUG)
{
- WATCHPOINT_ASSERT(ptr->ketama.continuum[pointer_index].value <= ptr->ketama.continuum[pointer_index + 1].value);
+ for (uint32_t pointer_index= 0; memcached_server_count(ptr) && pointer_index < ((live_servers * MEMCACHED_POINTS_PER_SERVER) - 1); pointer_index++)
+ {
+ WATCHPOINT_ASSERT(ptr->ketama.continuum[pointer_index].value <= ptr->ketama.continuum[pointer_index + 1].value);
+ }
}
-#endif
return MEMCACHED_SUCCESS;
}
+static memcached_return_t server_add(memcached_st *ptr,
+ const memcached_string_t& hostname,
+ in_port_t port,
+ uint32_t weight,
+ memcached_connection_t type)
+{
+ assert_msg(ptr, "Programmer mistake, somehow server_add() was passed a NULL memcached_st");
+ if ( (ptr->flags.use_udp and type != MEMCACHED_CONNECTION_UDP)
+ or ( (type == MEMCACHED_CONNECTION_UDP) and (not ptr->flags.use_udp) ) )
+ {
+ return memcached_set_error(*ptr, MEMCACHED_INVALID_HOST_PROTOCOL, MEMCACHED_AT);
+ }
+
+ memcached_server_st *new_host_list= static_cast<memcached_server_st*>(libmemcached_realloc(ptr, memcached_server_list(ptr),
+ sizeof(memcached_server_st) * (ptr->number_of_hosts + 1)));
+
+ if (not new_host_list)
+ {
+ return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+ }
+
+ memcached_server_list_set(ptr, new_host_list);
+
+ /* TODO: Check return type */
+ memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, memcached_server_count(ptr));
+
+ if (not __server_create_with(ptr, instance, hostname, port, weight, type))
+ {
+ return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT);
+ }
+
+ if (weight > 1)
+ {
+ ptr->ketama.weighted= true;
+ }
+
+ ptr->number_of_hosts++;
+
+ // @note we place the count in the bottom of the server list
+ instance= memcached_server_instance_fetch(ptr, 0);
+ memcached_servers_set_count(instance, memcached_server_count(ptr));
+
+ return run_distribution(ptr);
+}
+
memcached_return_t memcached_server_push(memcached_st *ptr, const memcached_server_list_st list)
{
instance= memcached_server_instance_fetch(ptr, memcached_server_count(ptr));
WATCHPOINT_ASSERT(instance);
- if (not __server_create_with(ptr, instance, list[x].hostname,
- list[x].port, list[x].weight, list[x].type))
+ memcached_string_t hostname= { memcached_string_make_from_cstr(list[x].hostname) };
+ if (__server_create_with(ptr, instance,
+ hostname,
+ list[x].port, list[x].weight, list[x].type) == NULL)
{
return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT);
}
const char *filename,
uint32_t weight)
{
- if (! filename)
+ if (ptr == NULL)
+ {
return MEMCACHED_FAILURE;
+ }
- return server_add(ptr, filename, 0, weight, MEMCACHED_CONNECTION_UNIX_SOCKET);
+ memcached_string_t _filename= { memcached_string_make_from_cstr(filename) };
+ if (memcached_is_valid_servername(_filename) == false)
+ {
+ memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, memcached_literal_param("Invalid filename for socket provided"));
+ }
+
+ return server_add(ptr, _filename, 0, weight, MEMCACHED_CONNECTION_UNIX_SOCKET);
}
memcached_return_t memcached_server_add_udp(memcached_st *ptr,
in_port_t port,
uint32_t weight)
{
+ if (ptr == NULL)
+ {
+ return MEMCACHED_INVALID_ARGUMENTS;
+ }
+
if (not port)
+ {
port= MEMCACHED_DEFAULT_PORT;
+ }
if (not hostname)
+ {
hostname= "localhost";
+ }
+
+ memcached_string_t _hostname= { memcached_string_make_from_cstr(hostname) };
+ if (memcached_is_valid_servername(_hostname) == false)
+ {
+ memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, memcached_literal_param("Invalid hostname provided"));
+ }
- return server_add(ptr, hostname, port, weight, MEMCACHED_CONNECTION_UDP);
+ return server_add(ptr, _hostname, port, weight, MEMCACHED_CONNECTION_UDP);
}
memcached_return_t memcached_server_add(memcached_st *ptr,
in_port_t port,
uint32_t weight)
{
- if (not port)
- port= MEMCACHED_DEFAULT_PORT;
-
- if (not hostname)
- hostname= "localhost";
-
- return server_add(ptr, hostname, port, weight, hostname[0] == '/' ? MEMCACHED_CONNECTION_UNIX_SOCKET : MEMCACHED_CONNECTION_TCP);
-}
-
-static memcached_return_t server_add(memcached_st *ptr, const char *hostname,
- in_port_t port,
- uint32_t weight,
- memcached_connection_t type)
-{
-
- if ( (ptr->flags.use_udp and type != MEMCACHED_CONNECTION_UDP)
- or ( (type == MEMCACHED_CONNECTION_UDP) and (not ptr->flags.use_udp) ) )
+ if (ptr == NULL)
{
- return MEMCACHED_INVALID_HOST_PROTOCOL;
+ return MEMCACHED_INVALID_ARGUMENTS;
}
- memcached_server_st *new_host_list= static_cast<memcached_server_st*>(libmemcached_realloc(ptr, memcached_server_list(ptr),
- sizeof(memcached_server_st) * (ptr->number_of_hosts + 1)));
-
- if (not new_host_list)
- return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
-
- memcached_server_list_set(ptr, new_host_list);
-
- /* TODO: Check return type */
- memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, memcached_server_count(ptr));
-
- if (not __server_create_with(ptr, instance, hostname, port, weight, type))
+ if (port == 0)
{
- return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT);
+ port= MEMCACHED_DEFAULT_PORT;
}
- if (weight > 1)
+ size_t hostname_length= hostname ? strlen(hostname) : 0;
+ if (hostname_length == 0)
{
- ptr->ketama.weighted= true;
+ hostname= "localhost";
+ hostname_length= sizeof("localhost") -1;
}
- ptr->number_of_hosts++;
+ memcached_string_t _hostname= { hostname, hostname_length };
- // @note we place the count in the bottom of the server list
- instance= memcached_server_instance_fetch(ptr, 0);
- memcached_servers_set_count(instance, memcached_server_count(ptr));
+ if (memcached_is_valid_servername(_hostname) == false)
+ {
+ return memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, memcached_literal_param("Invalid hostname provided"));
+ }
- return run_distribution(ptr);
+ return server_add(ptr, _hostname, port, weight, _hostname.c_str[0] == '/' ? MEMCACHED_CONNECTION_UNIX_SOCKET : MEMCACHED_CONNECTION_TCP);
}
memcached_return_t memcached_server_add_parsed(memcached_st *ptr,
memcpy(buffer, hostname, hostname_length);
buffer[hostname_length]= 0;
- return server_add(ptr, buffer,
+ memcached_string_t _hostname= { buffer, hostname_length };
+
+ return server_add(ptr, _hostname,
port,
weight,
MEMCACHED_CONNECTION_TCP);
libmemcached/protocol/binary_handler.h \
libmemcached/protocol/common.h \
libmemcached/response.h \
+ libmemcached/server.hpp \
libmemcached/server_instance.h \
libmemcached/string.hpp \
libmemcached/virtual_bucket.h
libmemcached/watchpoint.h
lib_LTLIBRARIES+= libmemcached/libmemcached.la
-libmemcached_libmemcached_la_CFLAGS= \
- ${AM_CFLAGS} \
- ${NO_CONVERSION} \
- -DBUILDING_LIBMEMCACHED
+libmemcached_libmemcached_la_CFLAGS= -DBUILDING_LIBMEMCACHED
-libmemcached_libmemcached_la_CXXFLAGS= \
- ${AM_CXXFLAGS} \
- ${NO_CONVERSION} \
- -DBUILDING_LIBMEMCACHED
+libmemcached_libmemcached_la_CXXFLAGS= -DBUILDING_LIBMEMCACHED
libmemcached_libmemcached_la_SOURCES+= \
${libhashkit_libhashkit_la_SOURCES} \
libmemcached_libmemcached_la_DEPENDENCIES=
libmemcached_libmemcached_la_LIBADD= $(LIBM)
-libmemcached_libmemcached_la_LDFLAGS+= ${AM_LDFLAGS} -version-info ${MEMCACHED_LIBRARY_VERSION}
+libmemcached_libmemcached_la_LDFLAGS+= -version-info ${MEMCACHED_LIBRARY_VERSION}
libmemcached_libmemcached_la_LIBADD+= $(LTLIBSASL) $(LTLIBSASL2)
libmemcached_libmemcached_la_SOURCES += libmemcached/sasl.cc
+if HAVE_SASL
+libmemcached_libmemcached_la_CXXFLAGS+= ${PTHREAD_CFLAGS}
+libmemcached_libmemcached_la_LIBADD+= ${PTHREAD_LIBS}
+endif
if HAVE_DTRACE
BUILT_SOURCES+= libmemcached/dtrace_probes.h
memcached_return_t initialize_query(memcached_st *self)
{
if (not self)
+ {
return MEMCACHED_INVALID_ARGUMENTS;
+ }
self->query_id++;
memcached_return_t initialize_const_query(const memcached_st *self)
{
if (not self)
+ {
return MEMCACHED_INVALID_ARGUMENTS;
+ }
if (memcached_server_count(self) == 0)
{
}
}
- ptr->server_failure_counter= 0;
*nread = (ssize_t)(buffer_ptr - (char*)buffer);
+
return MEMCACHED_SUCCESS;
}
self->distribution= MEMCACHED_DISTRIBUTION_MODULA;
if (not hashkit_create(&self->hashkit))
+ {
return false;
+ }
+
+ self->server_info.version= 0;
self->ketama.continuum= NULL;
self->ketama.continuum_count= 0;
self->snd_timeout= 0;
self->rcv_timeout= 0;
- self->server_failure_limit= 0;
+ self->server_failure_limit= MEMCACHED_SERVER_FAILURE_LIMIT;
self->query_id= 1; // 0 is considered invalid
/* TODO, Document why we picked these defaults */
self->io_key_prefetch= 0;
self->poll_timeout= MEMCACHED_DEFAULT_TIMEOUT;
self->connect_timeout= MEMCACHED_DEFAULT_CONNECT_TIMEOUT;
- self->retry_timeout= 0;
+ self->retry_timeout= MEMCACHED_SERVER_FAILURE_RETRY_TIMEOUT;
self->send_size= -1;
self->recv_size= -1;
memcached_server_free(ptr->last_disconnected_server);
if (ptr->on_cleanup)
+ {
ptr->on_cleanup(ptr);
+ }
libmemcached_free(ptr, ptr->ketama.continuum);
memcached_set_processing_input(ptr, false);
#endif
- if (! _memcached_init(ptr))
+ if (_memcached_init(ptr) == false)
{
memcached_free(ptr);
return NULL;
}
- if (! memcached_result_create(ptr, &ptr->result))
+ if (memcached_result_create(ptr, &ptr->result) == NULL)
{
memcached_free(ptr);
return NULL;
}
if (not length)
+ {
return self;
+ }
memcached_return_t rc= memcached_parse_configuration(self, string, length);
{
WATCHPOINT_ASSERT(ptr);
if (not ptr)
+ {
return MEMCACHED_INVALID_ARGUMENTS;
+ }
bool stored_is_allocated= memcached_is_allocated(ptr);
uint64_t query_id= ptr->query_id;
void memcached_servers_reset(memcached_st *self)
{
- if (not self)
- return;
-
- memcached_server_list_free(memcached_server_list(self));
+ if (self)
+ {
+ memcached_server_list_free(memcached_server_list(self));
- memcached_server_list_set(self, NULL);
- self->number_of_hosts= 0;
- memcached_server_free(self->last_disconnected_server);
- self->last_disconnected_server= NULL;
- self->server_failure_limit= 0;
+ memcached_server_list_set(self, NULL);
+ self->number_of_hosts= 0;
+ memcached_server_free(self->last_disconnected_server);
+ self->last_disconnected_server= NULL;
+ }
}
void memcached_reset_last_disconnected_server(memcached_st *self)
{
- if (not self)
- return;
-
- memcached_server_free(self->last_disconnected_server);
- self->last_disconnected_server= NULL;
+ if (self)
+ {
+ memcached_server_free(self->last_disconnected_server);
+ self->last_disconnected_server= NULL;
+ }
}
void memcached_free(memcached_st *ptr)
{
- if (not ptr)
- return;
-
- _free(ptr, true);
+ if (ptr)
+ {
+ _free(ptr, true);
+ }
}
/*
new_clone->tcp_keepidle= source->tcp_keepidle;
if (memcached_server_count(source))
+ {
rc= memcached_push(new_clone, source);
+ }
- if (rc != MEMCACHED_SUCCESS)
+ if (memcached_failed(rc))
{
memcached_free(new_clone);
if (LIBMEMCACHED_WITH_SASL_SUPPORT and source->sasl.callbacks)
{
- if (memcached_clone_sasl(new_clone, source) != MEMCACHED_SUCCESS)
+ if (memcached_failed(memcached_clone_sasl(new_clone, source)))
{
memcached_free(new_clone);
return NULL;
}
}
- rc= run_distribution(new_clone);
-
- if (rc != MEMCACHED_SUCCESS)
+ if (memcached_failed(run_distribution(new_clone)))
{
memcached_free(new_clone);
}
if (source->on_clone)
+ {
source->on_clone(new_clone, source);
+ }
return new_clone;
}
#include <libmemcached/flush_buffers.h>
#include <libmemcached/get.h>
#include <libmemcached/hash.h>
+#include <libmemcached/namespace.h>
#include <libmemcached/options.h>
#include <libmemcached/parse.h>
#include <libmemcached/quit.h>
memcached_server_distribution_t distribution;
hashkit_st hashkit;
+ struct {
+ unsigned int version;
+ } server_info;
uint32_t number_of_hosts;
memcached_server_st *servers;
memcached_server_st *last_disconnected_server;
uint32_t io_key_prefetch;
uint32_t tcp_keepidle;
int32_t poll_timeout;
- int32_t connect_timeout;
+ int32_t connect_timeout; // How long we will wait on connect() before we will timeout
int32_t retry_timeout;
int send_size;
int recv_size;
return memcached_strerror(NULL, rc);
}
+ bool error(std::string& error_message) const
+ {
+ if (memcached_failed(memcached_last_error(memc)))
+ {
+ error_message+= memcached_last_error_message(memc);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool error() const
+ {
+ if (memcached_failed(memcached_last_error(memc)))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ bool error(memcached_return_t& arg) const
+ {
+ arg= memcached_last_error(memc);
+ return memcached_failed(arg);
+ }
bool setBehavior(memcached_behavior_t flag, uint64_t data)
{
key.c_str(), key.length(),
&value[0], value.size(),
expiration, flags);
- return (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+ return memcached_success(rc);
}
/**
*
*/
-#include "config.h"
-
#include <libmemcached/protocol/common.h>
#include <libmemcached/byteorder.h>
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached library
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * 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.
+ *
+ */
+
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#include <stdlib.h>
#include <string.h>
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached library
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * 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.
+ *
+ */
+
/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#include "libmemcached/protocol/common.h"
+#include <libmemcached/protocol/common.h>
#include <sys/types.h>
#include <inttypes.h>
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached library
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * 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.
+ *
+ */
+
/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-#include "libmemcached/protocol/common.h"
+#include <libmemcached/protocol/common.h>
#include <stdlib.h>
#include <sys/types.h>
if (io_death)
{
- ptr->server_failure_counter++;
- set_last_disconnected_host(ptr);
+ memcached_mark_server_for_timeout(ptr);
}
}
MEMCACHED_PARSE_USER_ERROR,
MEMCACHED_DEPRECATED,
MEMCACHED_IN_PROGRESS,
+ MEMCACHED_SERVER_TEMPORARILY_DISABLED,
MEMCACHED_MAXIMUM_RETURN /* Always add new error code before */
};
#if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT
#include <sasl/sasl.h>
+#include <pthread.h>
void memcached_set_sasl_callbacks(memcached_st *ptr,
const sasl_callback_t *callbacks)
return MEMCACHED_SUCCESS;
}
+extern "C" {
+
+static void sasl_shutdown_function()
+{
+ sasl_done();
+}
+
+static volatile int sasl_startup_state= SASL_OK;
+pthread_mutex_t sasl_startup_state_LOCK= PTHREAD_MUTEX_INITIALIZER;
+static pthread_once_t sasl_startup_once= PTHREAD_ONCE_INIT;
+static void sasl_startup_function(void)
+{
+ sasl_startup_state= sasl_client_init(NULL);
+
+ if (sasl_startup_state == SASL_OK)
+ {
+ (void)atexit(sasl_shutdown_function);
+ }
+}
+
+} // extern "C"
+
memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *server)
{
if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
return rc;
}
- int ret;
- if ((ret= sasl_client_init(NULL)) != SASL_OK)
+ int pthread_error;
+ if ((pthread_error= pthread_once(&sasl_startup_once, sasl_startup_function)) != 0)
{
- const char *sasl_error_msg= sasl_errstring(ret, NULL, NULL);
+ return memcached_set_errno(*server, pthread_error, MEMCACHED_AT);
+ }
+
+ (void)pthread_mutex_lock(&sasl_startup_state_LOCK);
+ if (sasl_startup_state != SASL_OK)
+ {
+ const char *sasl_error_msg= sasl_errstring(sasl_startup_state, NULL, NULL);
return memcached_set_error(*server, MEMCACHED_AUTH_PROBLEM, MEMCACHED_AT,
memcached_string_make_from_cstr(sasl_error_msg));
}
+ (void)pthread_mutex_unlock(&sasl_startup_state_LOCK);
sasl_conn_t *conn;
+ int ret;
if ((ret= sasl_client_new("memcached", server->hostname, laddr, raddr, server->root->sasl.callbacks, 0, &conn) ) != SASL_OK)
{
const char *sasl_error_msg= sasl_errstring(ret, NULL, NULL);
+
+ sasl_dispose(&conn);
+
return memcached_set_error(*server, MEMCACHED_AUTH_PROBLEM, MEMCACHED_AT,
memcached_string_make_from_cstr(sasl_error_msg));
}
if (ret != SASL_OK and ret != SASL_CONTINUE)
{
const char *sasl_error_msg= sasl_errstring(ret, NULL, NULL);
+
+ sasl_dispose(&conn);
+
return memcached_set_error(*server, MEMCACHED_AUTH_PROBLEM, MEMCACHED_AT,
memcached_string_make_from_cstr(sasl_error_msg));
}
return MEMCACHED_INVALID_ARGUMENTS;
}
+ memcached_return_t ret;
+ if (memcached_failed(ret= memcached_behavior_set(ptr, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1)))
+ {
+ return memcached_set_error(*ptr, ret, MEMCACHED_AT, memcached_literal_param("Unable change to binary protocol which is required for SASL."));
+ }
+
memcached_destroy_sasl_auth_data(ptr);
sasl_callback_t *callbacks= (sasl_callback_t*)libmemcached_calloc(ptr, 4, sizeof(sasl_callback_t));
#include <libmemcached/common.h>
static inline void _server_init(memcached_server_st *self, memcached_st *root,
- const char *hostname, in_port_t port,
+ const memcached_string_t& hostname,
+ in_port_t port,
uint32_t weight, memcached_connection_t type)
{
self->options.is_shutting_down= false;
self->fd= -1;
self->io_bytes_sent= 0;
self->server_failure_counter= 0;
+ self->server_failure_counter_query_id= 0;
self->weight= weight ? weight : 1; // 1 is the default weight value
WATCHPOINT_SET(self->io_wait_count.read= 0);
WATCHPOINT_SET(self->io_wait_count.write= 0);
self->address_info_next= NULL;
self->state= MEMCACHED_SERVER_STATE_NEW;
+ self->next_retry= 0;
+ self->root= root;
if (root)
{
- self->next_retry= root->retry_timeout;
+ self->version= ++root->server_info.version;
}
else
{
- self->next_retry= 0;
+ self->version= UINT_MAX;
}
-
- self->root= root;
self->limit_maxbytes= 0;
- if (hostname)
- {
- strncpy(self->hostname, hostname, NI_MAXHOST - 1);
- }
- else
- {
- self->hostname[0]= 0;
- }
+ memcpy(self->hostname, hostname.c_str, hostname.size);
+ self->hostname[hostname.size]= 0;
}
static memcached_server_st *_server_create(memcached_server_st *self, const memcached_st *memc)
self= (memcached_server_st *)libmemcached_malloc(memc, sizeof(memcached_server_st));
if (not self)
+ {
return NULL; /* MEMCACHED_MEMORY_ALLOCATION_FAILURE */
+ }
self->options.is_allocated= true;
}
return self;
}
-memcached_server_st *__server_create_with(const memcached_st *memc,
+memcached_server_st *__server_create_with(memcached_st *memc,
memcached_server_write_instance_st self,
- const char *hostname, in_port_t port,
- uint32_t weight, memcached_connection_t type)
+ const memcached_string_t& hostname,
+ const in_port_t port,
+ uint32_t weight,
+ const memcached_connection_t type)
{
+ if (memcached_is_valid_servername(hostname) == false)
+ {
+ memcached_set_error(*memc, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, memcached_literal_param("Invalid hostname provided"));
+ return NULL;
+ }
+
self= _server_create(self, memc);
if (not self)
{
freeaddrinfo(self->address_info);
self->address_info= NULL;
+ self->address_info_next= NULL;
}
memcached_error_free(*self);
If we do not have a valid object to clone from, we toss an error.
*/
memcached_server_st *memcached_server_clone(memcached_server_st *destination,
- const memcached_server_st *source)
+ memcached_server_st *source)
{
/* We just do a normal create if source is missing */
if (not source)
+ {
return NULL;
+ }
+ memcached_string_t hostname= { memcached_string_make_from_cstr(source->hostname) };
destination= __server_create_with(source->root, destination,
- source->hostname, source->port, source->weight,
+ hostname,
+ source->port, source->weight,
source->type);
if (not destination)
{
#pragma once
+#ifndef WIN32
+#include <netdb.h>
+#endif
+
enum memcached_server_state_t {
MEMCACHED_SERVER_STATE_NEW, // fd == -1, no address lookup has been done
MEMCACHED_SERVER_STATE_ADDRINFO, // ADDRRESS information has been gathered
MEMCACHED_SERVER_STATE_IN_PROGRESS,
- MEMCACHED_SERVER_STATE_CONNECTED
+ MEMCACHED_SERVER_STATE_CONNECTED,
+ MEMCACHED_SERVER_STATE_IN_TIMEOUT
};
struct memcached_server_st {
memcached_socket_t fd;
uint32_t io_bytes_sent; /* # bytes sent since last read */
uint32_t server_failure_counter;
+ uint64_t server_failure_counter_query_id;
uint32_t weight;
+ uint32_t version;
enum memcached_server_state_t state;
struct {
uint32_t read;
LIBMEMCACHED_LOCAL
memcached_server_st *memcached_server_clone(memcached_server_st *destination,
- const memcached_server_st *source);
+ memcached_server_st *source);
LIBMEMCACHED_API
memcached_server_instance_st memcached_server_get_last_disconnect(const memcached_st *ptr);
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached library
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * 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 <libmemcached/basic_string.h>
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include <cassert>
+
+static inline bool memcached_is_valid_servername(const memcached_string_t& arg)
+{
+ return arg.size > 0 or arg.size < NI_MAXHOST;
+}
+
+static inline void memcached_mark_server_as_clean(memcached_server_write_instance_st server)
+{
+ server->server_failure_counter= 0;
+ server->next_retry= 0;
+}
+
+
+static inline void set_last_disconnected_host(memcached_server_write_instance_st self)
+{
+ assert(self->root);
+ if (self->root == NULL)
+ {
+ return;
+ }
+
+ if (self->root->last_disconnected_server and self->root->last_disconnected_server->version == self->version)
+ {
+ return;
+ }
+
+ // const_cast
+ memcached_st *root= (memcached_st *)self->root;
+
+ memcached_server_free(root->last_disconnected_server);
+ root->last_disconnected_server= memcached_server_clone(NULL, self);
+ root->last_disconnected_server->version= self->version;
+}
+
+static inline void memcached_mark_server_for_timeout(memcached_server_write_instance_st server)
+{
+ if (server->state != MEMCACHED_SERVER_STATE_IN_TIMEOUT)
+ {
+ struct timeval next_time;
+ if (gettimeofday(&next_time, NULL) == 0)
+ {
+ server->next_retry= next_time.tv_sec +server->root->retry_timeout;
+ }
+ else
+ {
+ server->next_retry= 1; // Setting the value to 1 causes the timeout to occur immediatly
+ }
+
+ server->state= MEMCACHED_SERVER_STATE_IN_TIMEOUT;
+ if (server->server_failure_counter_query_id != server->root->query_id)
+ {
+ server->server_failure_counter++;
+ server->server_failure_counter_query_id= server->root->query_id;
+ }
+ set_last_disconnected_host(server);
+ }
+}
+
+LIBMEMCACHED_LOCAL
+ memcached_server_st *__server_create_with(memcached_st *memc,
+ memcached_server_write_instance_st host,
+ const memcached_string_t& hostname,
+ const in_port_t port,
+ uint32_t weight,
+ const memcached_connection_t type);
port= MEMCACHED_DEFAULT_PORT;
}
+
/* Increment count for hosts */
count= 1;
if (ptr != NULL)
return NULL;
}
+ memcached_string_t _hostname= { memcached_string_make_from_cstr(hostname) };
/* @todo Check return type */
- if (not __server_create_with(NULL, &new_host_list[count-1], hostname, port, weight, port ? MEMCACHED_CONNECTION_TCP : MEMCACHED_CONNECTION_UNIX_SOCKET))
+ if (not __server_create_with(NULL, &new_host_list[count-1], _hostname, port, weight, port ? MEMCACHED_CONNECTION_TCP : MEMCACHED_CONNECTION_UNIX_SOCKET))
{
*error= memcached_set_errno(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT);
return NULL;
memcached_server_st *memcached_server_list(const memcached_st *self)
{
- return self->servers;
+ if (self)
+ {
+ return self->servers;
+ }
+
+ return NULL;
}
void memcached_server_list_set(memcached_st *self, memcached_server_st *list)
memcached_stat_st *memcached_stat(memcached_st *self, char *args, memcached_return_t *error)
{
+ memcached_return_t unused;
+ if (error == NULL)
+ {
+ error= &unused;
+ }
+
memcached_return_t rc;
if (memcached_failed(rc= initialize_query(self)))
{
- if (error)
- *error= rc;
+ *error= rc;
return NULL;
}
WATCHPOINT_ASSERT(error);
- unlikely (self->flags.use_udp)
+ if (self->flags.use_udp)
{
- if (error)
- *error= MEMCACHED_NOT_SUPPORTED;
+ *error= memcached_set_error(*self, MEMCACHED_NOT_SUPPORTED, MEMCACHED_AT);
return NULL;
}
if (not stats)
{
- if (error)
- *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+ *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
return NULL;
}
}
}
- if (error)
- *error= rc;
+ *error= rc;
return stats;
}
uint64_t cas,
memcached_storage_action_t verb)
{
- WATCHPOINT_ASSERT(!(value == NULL && value_length > 0));
-
memcached_return_t rc;
if (memcached_failed(rc= initialize_query(ptr)))
{
case MEMCACHED_IN_PROGRESS:
return "OPERATION IN PROCESS";
+ case MEMCACHED_SERVER_TEMPORARILY_DISABLED:
+ return "SERVER HAS FAILED AND IS DISABLED UNTIL TIMED RETRY";
+
default:
case MEMCACHED_MAXIMUM_RETURN:
return "INVALID memcached_return_t";
return -1;
}
- if (memcached_failed(*ret= memcached_behavior_set(memc_ptr, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1)))
- {
- memcached_free(memc_ptr);
- return false;
- }
-
if (memcached_failed(*ret= memcached_set_sasl_auth_data(memc_ptr, username, password)))
{
memcached_free(memc_ptr);
memcached_server_instance_st instance=
memcached_server_instance_by_position(memc_ptr, 0);
+#if 0
assert_msg(instance and instance->error_messages, " ");
+#endif
if (instance and instance->error_messages)
{
rc= memcached_server_error_return(instance);
return false;
}
- if (memcached_failed(*ret= memcached_behavior_set(memc_ptr, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1)))
- {
- memcached_free(memc_ptr);
- return false;
- }
-
if (memcached_failed(*ret= memcached_set_sasl_auth_data(memc_ptr, username, password)))
{
memcached_free(memc_ptr);
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include <libtest/common.h>
+
+namespace libtest {
+
+bool has_gearmand_binary()
+{
+#if defined(HAVE_GEARMAND_BINARY) && HAVE_GEARMAND_BINARY
+ if (access(GEARMAND_BINARY,R_OK|X_OK) == 0)
+ {
+ return true;
+ }
+#endif
+
+ return false;
+}
+
+bool has_memcached_binary()
+{
+#if defined(HAVE_MEMCACHED_BINARY) && HAVE_MEMCACHED_BINARY
+ if (access(MEMCACHED_BINARY,R_OK|X_OK) == 0)
+ {
+ return true;
+ }
+#endif
+
+ return false;
+}
+
+bool has_memcached_sasl_binary()
+{
+#if defined(HAVE_MEMCACHED_SASL_BINARY) && HAVE_MEMCACHED_SASL_BINARY
+ if (access(MEMCACHED_SASL_BINARY, R_OK|X_OK) == 0)
+ {
+ return true;
+ }
+#endif
+
+ return false;
+}
+
+}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+namespace libtest {
+
+LIBTEST_API
+bool has_memcached_binary();
+
+LIBTEST_API
+bool has_memcached_sasl_binary();
+
+LIBTEST_API
+bool has_gearmand_binary();
+
+} // namespace libtest
+
#include <libtest/common.h>
#include <libtest/blobslap_worker.h>
-#include <libtest/killpid.h>
-
-using namespace libtest;
#include <cassert>
#include <cerrno>
#pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
-using namespace libtest;
+namespace libtest {
class BlobslapWorker : public Server
{
return true;
}
-namespace libtest {
-
Server *build_blobslap_worker(in_port_t try_port)
{
return new BlobslapWorker(try_port);
}
-}
+} // namespace libtest
#include <fnmatch.h>
#endif
-static inline bool is_pid_valid(const pid_t pid)
-{
- return (pid > 1) ? true : false;
-}
+#include <libtest/test.hpp>
+
+#include <libtest/is_pid.hpp>
#include <libtest/gearmand.h>
#include <libtest/blobslap_worker.h>
#include <libtest/memcached.h>
#include <libtest/libtool.hpp>
+#include <libtest/killpid.h>
+#include <libtest/stats.h>
+#include <libtest/signal.h>
-#include <libtest/test.hpp>
#pragma once
#include <typeinfo>
-#include <libtest/strerror.h>
#if defined(HAVE_LIBMEMCACHED) && HAVE_LIBMEMCACHED
#include <libmemcached/memcached.h>
namespace libtest {
template <class T_comparable, class T_hint>
-bool _compare_true_hint(const char *file, int line, const char *func, T_comparable __expected, const char *assertation_label, T_hint __hint)
+bool _compare_truth_hint(const char *file, int line, const char *func, T_comparable __expected, const char *assertation_label, T_hint __hint)
{
if (__expected == false)
{
<< got_str
<< "\"";
}
-#if (defined(HAVE_LIBMEMCACHED) && HAVE_LIBMEMCACHED)
+#if defined(HAVE_LIBMEMCACHED) && HAVE_LIBMEMCACHED
else if (typeid(__expected) == typeid(memcached_return_t))
{
libtest::stream::make_cerr(file, line, func) << "Expected \""
return true;
}
+template <class T_comparable>
+bool _truth(const char *file, int line, const char *func, T_comparable __truth)
+{
+ if (bool(__truth))
+ {
+ libtest::stream::make_cerr(file, line, func) << "Assertion failed for " << func << "() with \"" << __truth << "\"";
+ return false;
+ }
+
+ return true;
+}
+
template <class T_comparable, class T_hint>
bool _compare_hint(const char *file, int line, const char *func, T_comparable __expected, T_comparable __actual, T_hint __hint)
{
if (__expected != __actual)
{
- libtest::stream::make_cerr(file, line, func) << "Expected \"" << __expected << "\" got \"" << __actual << "\" Additionally: \"" << __hint << "\"";
+ if (typeid(__expected) == typeid(test_return_t))
+ {
+ const char *expected_str= test_strerror(test_return_t(__expected));
+ const char *got_str= test_strerror(test_return_t(__actual));
+ libtest::stream::make_cerr(file, line, func) << "Expected \""
+ << expected_str
+ << "\" got \""
+ << got_str
+ << "\""
+ << " Additionally: \"" << __hint << "\"";
+ }
+#if defined(HAVE_LIBMEMCACHED) && HAVE_LIBMEMCACHED
+ else if (typeid(__expected) == typeid(memcached_return_t))
+ {
+ libtest::stream::make_cerr(file, line, func) << "Expected \""
+ << memcached_strerror(NULL, memcached_return_t(__expected))
+ << "\" got \""
+ << memcached_strerror(NULL, memcached_return_t(__actual)) << "\""
+ << " Additionally: \"" << __hint << "\"";
+ }
+#endif
+#if defined(HAVE_LIBGEARMAN) && HAVE_LIBGEARMAN
+ else if (typeid(__expected) == typeid(gearman_return_t))
+ {
+ libtest::stream::make_cerr(file, line, func) << "Expected \""
+ << gearman_strerror(gearman_return_t(__expected))
+ << "\" got \""
+ << gearman_strerror(gearman_return_t(__actual)) << "\""
+ << " Additionally: \"" << __hint << "\"";
+ }
+#endif
+ else
+ {
+ libtest::stream::make_cerr(file, line, func) << "Expected \"" << __expected << "\" got \"" << __actual << "\""
+ << " Additionally: \"" << __hint << "\"";
+ }
return false;
}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <libtest/common.h>
+
+
+namespace libtest {
+
+void create_core(void)
+{
+ if (getenv("LIBMEMCACHED_NO_COREDUMP") == NULL)
+ {
+ pid_t pid= fork();
+
+ if (pid == 0)
+ {
+ abort();
+ }
+ else
+ {
+ while (waitpid(pid, NULL, 0) != pid) {};
+ }
+ }
+}
+
+} // namespace libtest
#pragma once
+namespace libtest {
+
LIBTEST_API
void create_core(void);
+
+} // namespace libtest
#pragma once
enum test_return_t {
- TEST_SUCCESS= 0, /* Backwards compatibility */
+ TEST_SUCCESS,
TEST_FAILURE,
TEST_MEMORY_ALLOCATION_FAILURE,
TEST_SKIPPED,
};
-#define test_failed(__test_return_t) ((__test_return_t) != TEST_SUCCESS)
-#define test_success(__test_return_t) ((__test_return_t) == TEST_SUCCESS)
+static inline bool test_success(test_return_t rc)
+{
+ return (rc == TEST_SUCCESS);
+}
+
+static inline bool test_failed(test_return_t rc)
+{
+ return (rc != TEST_SUCCESS);
+}
{
_servers.set_sasl(username_arg, password_arg);
}
+
+ libtest::server_startup_st& servers()
+ {
+ return _servers;
+ }
/**
Runner represents the callers for the tests. If not implemented we will use
-rm -rf tmp_chroot
noinst_HEADERS+= \
+ libtest/binaries.h \
libtest/blobslap_worker.h \
libtest/callbacks.h \
libtest/cmdline.h \
libtest/framework.h \
libtest/gearmand.h \
libtest/get.h \
+ libtest/is_pid.hpp \
+ libtest/is_local.hpp \
libtest/killpid.h \
libtest/libtool.hpp \
libtest/memcached.h \
libtest/runner.h \
+ libtest/port.h \
libtest/server.h \
+ libtest/server_container.h \
libtest/signal.h \
+ libtest/socket.hpp \
libtest/stats.h \
libtest/stream.h \
libtest/strerror.h \
noinst_LTLIBRARIES+= libtest/libtest.la
libtest_libtest_la_SOURCES= \
+ libtest/binaries.cc \
libtest/cmdline.cc \
+ libtest/core.cc \
libtest/framework.cc \
+ libtest/is_local.cc \
libtest/killpid.cc \
libtest/libtool.cc \
+ libtest/port.cc \
libtest/runner.cc \
libtest/server.cc \
+ libtest/server_container.cc \
libtest/signal.cc \
+ libtest/socket.cc \
+ libtest/strerror.cc \
libtest/test.cc
libtest_libtest_la_CXXFLAGS= ${AM_CXXFLAGS}
libtest_unittest_LDADD+= libtest/libtest.la
libtest_unittest_SOURCES= libtest/unittest.cc
check_PROGRAMS+= libtest/unittest
+noinst_PROGRAMS+= libtest/unittest
test-unittest: libtest/unittest
@libtest/unittest
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <libtest/common.h>
+
+
+namespace libtest {
+
+bool test_is_local()
+{
+ return (getenv("LIBTEST_LOCAL"));
+}
+
+} // namespace libtest
+
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+namespace libtest {
+
+LIBTEST_API
+bool test_is_local();
+
+} // namespace libtest
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+static inline bool is_pid_valid(const pid_t pid)
+{
+ return (pid > 1) ? true : false;
+}
+
return true;
}
-
-pid_t kill_file(const std::string &filename)
+bool check_pid(const std::string &filename)
{
- pid_t ret= -1;
+ if (filename.empty())
+ {
+ return false;
+ }
+
FILE *fp;
+ if ((fp= fopen(filename.c_str(), "r")))
+ {
+ char pid_buffer[1024];
+
+ char *ptr= fgets(pid_buffer, sizeof(pid_buffer), fp);
+ fclose(fp);
+ if (ptr)
+ {
+ pid_t pid= (pid_t)atoi(pid_buffer);
+ if (pid > 0)
+ {
+ return (::kill(pid, 0) == 0);
+ }
+ }
+ }
+
+ return false;
+}
+
+
+bool kill_file(const std::string &filename)
+{
if (filename.empty())
- return ret;
+ {
+ return true;
+ }
+ FILE *fp;
if ((fp= fopen(filename.c_str(), "r")))
{
char pid_buffer[1024];
pid_t pid= (pid_t)atoi(pid_buffer);
if (pid != 0)
{
- kill_pid(pid);
+ bool ret= kill_pid(pid);
unlink(filename.c_str()); // If this happens we may be dealing with a dead server that left its pid file.
+
+ return ret;
}
}
}
- return ret;
+ return false;
}
#define STRINGIFY(x) #x
bool kill_pid(pid_t pid_arg);
-pid_t kill_file(const std::string &filename);
+bool kill_file(const std::string &filename);
+
+bool check_pid(const std::string &filename);
pid_t get_pid_from_file(const std::string &filename, std::stringstream& error_message);
+
+static inline bool check_pid(pid_t pid_arg)
+{
+ return (pid_arg > 1);
+}
// Memcached is slow to start, so we need to do this
if (not pid_file().empty())
{
- Wait wait(pid_file(), 0);
-
- if (error_is_ok and not wait.successful())
+ if (error_is_ok and not wait_for_pidfile())
{
Error << "Pidfile was not found:" << pid_file();
return -1;
}
pid_t local_pid;
- memcached_return_t rc;
+ memcached_return_t rc= MEMCACHED_SUCCESS;
if (has_socket())
{
- if (username().empty())
- {
- local_pid= libmemcached_util_getpid(socket().c_str(), 0, &rc);
- }
- else
- {
- local_pid= libmemcached_util_getpid2(socket().c_str(), 0, username().c_str(), password().c_str(), &rc);
- }
+ local_pid= libmemcached_util_getpid(socket().c_str(), 0, &rc);
}
else
{
- if (username().empty())
- {
- local_pid= libmemcached_util_getpid(hostname().c_str(), port(), &rc);
- }
- else
- {
- local_pid= libmemcached_util_getpid2(hostname().c_str(), port(), username().c_str(), password().c_str(), &rc);
- }
+ local_pid= libmemcached_util_getpid(hostname().c_str(), port(), &rc);
}
if (error_is_ok and ((memcached_failed(rc) or not is_pid_valid(local_pid))))
// Memcached is slow to start, so we need to do this
if (not pid_file().empty())
{
- Wait wait(pid_file(), 0);
-
- if (not wait.successful())
+ if (not wait_for_pidfile())
{
Error << "Pidfile was not found:" << pid_file();
return -1;
if (has_socket())
{
- if (username().empty())
- {
ret= libmemcached_util_ping(socket().c_str(), 0, &rc);
- }
- else
- {
- ret= libmemcached_util_ping2(socket().c_str(), 0, username().c_str(), password().c_str(), &rc);
- }
}
else
{
- if (username().empty())
- {
- ret= libmemcached_util_ping(hostname().c_str(), port(), &rc);
- }
- else
- {
- ret= libmemcached_util_ping2(hostname().c_str(), port(), username().c_str(), password().c_str(), &rc);
- }
+ ret= libmemcached_util_ping(hostname().c_str(), port(), &rc);
}
if (memcached_failed(rc) or not ret)
{
- if (username().empty())
- {
- Error << "libmemcached_util_ping(" << hostname() << ", " << port() << ") error: " << memcached_strerror(NULL, rc);
- }
- else
- {
- Error << "libmemcached_util_ping2(" << hostname() << ", " << port() << ", " << username() << ", " << password() << ") error: " << memcached_strerror(NULL, rc);
- }
+ Error << "libmemcached_util_ping(" << hostname() << ", " << port() << ") error: " << memcached_strerror(NULL, rc);
}
return ret;
return MEMCACHED_SASL_BINARY;
}
+ pid_t get_pid(bool error_is_ok)
+ {
+ // Memcached is slow to start, so we need to do this
+ if (not pid_file().empty())
+ {
+ if (error_is_ok and not wait_for_pidfile())
+ {
+ Error << "Pidfile was not found:" << pid_file();
+ return -1;
+ }
+ }
+
+ pid_t local_pid;
+ memcached_return_t rc;
+ if (has_socket())
+ {
+ local_pid= libmemcached_util_getpid2(socket().c_str(), 0, username().c_str(), password().c_str(), &rc);
+ }
+ else
+ {
+ local_pid= libmemcached_util_getpid2(hostname().c_str(), port(), username().c_str(), password().c_str(), &rc);
+ }
+
+ if (error_is_ok and ((memcached_failed(rc) or not is_pid_valid(local_pid))))
+ {
+ Error << "libmemcached_util_getpid2(" << memcached_strerror(NULL, rc) << ") username: " << username() << " password: " << password() << " pid: " << local_pid << " for:" << *this;
+ }
+
+ return local_pid;
+ }
+
+ bool ping()
+ {
+ // Memcached is slow to start, so we need to do this
+ if (not pid_file().empty())
+ {
+ if (not wait_for_pidfile())
+ {
+ Error << "Pidfile was not found:" << pid_file();
+ return -1;
+ }
+ }
+
+ memcached_return_t rc;
+ bool ret;
+
+ if (has_socket())
+ {
+ ret= libmemcached_util_ping2(socket().c_str(), 0, username().c_str(), password().c_str(), &rc);
+ }
+ else
+ {
+ ret= libmemcached_util_ping2(hostname().c_str(), port(), username().c_str(), password().c_str(), &rc);
+ }
+
+ if (memcached_failed(rc) or not ret)
+ {
+ Error << "libmemcached_util_ping2(" << hostname() << ", " << port() << ", " << username() << ", " << password() << ") error: " << memcached_strerror(NULL, rc);
+ }
+
+ return ret;
+ }
+
};
libtest::Server *build_memcached_sasl(const std::string& hostname, const in_port_t try_port, const std::string& username, const std::string &password)
{
+ if (username.empty())
+ {
+ return new MemcachedSaSL(hostname, try_port, false, "memcached", "memcached");
+ }
+
return new MemcachedSaSL(hostname, try_port, false, username, password);
}
libtest::Server *build_memcached_sasl_socket(const std::string& socket_file, const in_port_t try_port, const std::string& username, const std::string &password)
{
+ if (username.empty())
+ {
+ return new MemcachedSaSL(socket_file, try_port, true, "memcached", "memcached");
+ }
+
return new MemcachedSaSL(socket_file, try_port, true, username, password);
}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <libtest/common.h>
+
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <ctime>
+#include <fnmatch.h>
+#include <iostream>
+
+#include <signal.h>
+
+#include <libtest/stats.h>
+#include <libtest/signal.h>
+
+#ifndef __INTEL_COMPILER
+#pragma GCC diagnostic ignored "-Wold-style-cast"
+#endif
+
+using namespace libtest;
+
+static in_port_t global_port= 0;
+static in_port_t global_max_port= 0;
+
+namespace libtest {
+
+in_port_t default_port()
+{
+ return global_port;
+}
+
+void set_default_port(in_port_t port)
+{
+ global_port= port;
+}
+
+in_port_t max_port()
+{
+ return global_max_port;
+}
+
+void set_max_port(in_port_t port)
+{
+ if (port > global_max_port)
+ {
+ global_max_port= port;
+ }
+
+ global_max_port= port;
+}
+
+} // namespace libtest
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+/*
+ Structures for generic tests.
+*/
+
+#pragma once
+
+namespace libtest {
+
+LIBTEST_API
+in_port_t default_port();
+
+LIBTEST_API
+void set_default_port(in_port_t port);
+
+LIBTEST_API
+in_port_t max_port();
+
+LIBTEST_API
+void set_max_port(in_port_t port);
+
+} // namespace libtest
}
}
-std::string server_startup_st::option_string() const
-{
- std::string temp= server_list;
- rtrim(temp);
- return temp;
-}
-
// If the server exists, kill it
bool Server::cycle()
{
return false;
}
+bool Server::wait_for_pidfile() const
+{
+ Wait wait(pid_file(), 4);
+
+ return wait.successful();
+}
+
bool Server::start()
{
// If we find that we already have a pid then kill it.
return false;
}
-void server_startup_st::push_server(Server *arg)
-{
- servers.push_back(arg);
-
- char port_str[NI_MAXSERV];
- snprintf(port_str, sizeof(port_str), "%u", int(arg->port()));
-
- std::string server_config_string;
- if (arg->has_socket())
- {
- server_config_string+= "--socket=";
- server_config_string+= '"';
- server_config_string+= arg->socket();
- server_config_string+= '"';
- server_config_string+= " ";
- }
- else
- {
- server_config_string+= "--server=";
- server_config_string+= arg->hostname();
- server_config_string+= ":";
- server_config_string+= port_str;
- server_config_string+= " ";
- }
-
- server_list+= server_config_string;
-
-}
-
-Server* server_startup_st::pop_server()
-{
- Server *tmp= servers.back();
- servers.pop_back();
- return tmp;
-}
-
-void server_startup_st::shutdown(bool remove)
-{
- if (remove)
- {
- for (std::vector<Server *>::iterator iter= servers.begin(); iter != servers.end(); iter++)
- {
- delete *iter;
- }
- servers.clear();
- }
- else
- {
- for (std::vector<Server *>::iterator iter= servers.begin(); iter != servers.end(); iter++)
- {
- if ((*iter)->has_pid() and not (*iter)->kill((*iter)->pid()))
- {
- Error << "Unable to kill:" << *(*iter);
- }
- }
- }
-}
-
-server_startup_st::~server_startup_st()
-{
- shutdown(true);
-}
-
-bool server_startup_st::is_debug() const
-{
- return bool(getenv("LIBTEST_MANUAL_GDB"));
-}
-
-bool server_startup_st::is_valgrind() const
-{
- return bool(getenv("LIBTEST_MANUAL_VALGRIND"));
-}
-
-bool server_startup_st::is_helgrind() const
-{
- return bool(getenv("LIBTEST_MANUAL_HELGRIND"));
-}
-
-
-bool server_startup(server_startup_st& construct, const std::string& server_type, in_port_t try_port, int argc, const char *argv[])
-{
- Outn();
- (void)try_port;
-
- // Look to see if we are being provided ports to use
- {
- char variable_buffer[1024];
- snprintf(variable_buffer, sizeof(variable_buffer), "LIBTEST_PORT_%lu", (unsigned long)construct.count());
-
- char *var;
- if ((var= getenv(variable_buffer)))
- {
- in_port_t tmp= in_port_t(atoi(var));
-
- if (tmp > 0)
- try_port= tmp;
- }
- }
-
- libtest::Server *server= NULL;
- if (0)
- { }
- else if (server_type.compare("gearmand") == 0)
- {
- if (GEARMAND_BINARY)
- {
- if (HAVE_LIBGEARMAN)
- {
- server= build_gearmand("localhost", try_port);
- }
- else
- {
- Error << "Libgearman was not found";
- }
- }
- else
- {
- Error << "No gearmand binary is available";
- }
- }
- else if (server_type.compare("blobslap_worker") == 0)
- {
- if (GEARMAND_BINARY and GEARMAND_BLOBSLAP_WORKER)
- {
- if (HAVE_LIBGEARMAN)
- {
- server= build_blobslap_worker(try_port);
- }
- else
- {
- Error << "Libgearman was not found";
- }
- }
- else
- {
- Error << "No gearmand binary is available";
- }
- }
- else if (server_type.compare("memcached-sasl") == 0)
- {
- if (MEMCACHED_SASL_BINARY)
- {
- if (HAVE_LIBMEMCACHED)
- {
- server= build_memcached_sasl("localhost", try_port, construct.username(), construct.password());
- }
- else
- {
- Error << "Libmemcached was not found";
- }
- }
- else
- {
- Error << "No memcached binary that was compiled with sasl is available";
- }
- }
- else if (server_type.compare("memcached") == 0)
- {
- if (MEMCACHED_BINARY)
- {
- if (HAVE_LIBMEMCACHED)
- {
- server= build_memcached("localhost", try_port);
- }
- else
- {
- Error << "Libmemcached was not found";
- }
- }
- else
- {
- Error << "No memcached binary is available";
- }
- }
- else
- {
- Error << "Failed to start " << server_type << ", no support was found to be compiled in for it.";
- }
-
- if (server == NULL)
- {
- Error << "Failure occured while creating server: " << server_type;
- return false;
- }
-
- /*
- We will now cycle the server we have created.
- */
- if (not server->cycle())
- {
- Error << "Could not start up server " << *server;
- delete server;
- return false;
- }
-
- server->build(argc, argv);
-
- if (construct.is_debug())
- {
- Out << "Pausing for startup, hit return when ready.";
- std::string gdb_command= server->base_command();
- std::string options;
- Out << "run " << server->args(options);
- getchar();
- }
- else if (not server->start())
- {
- Error << "Failed to start " << *server;
- delete server;
- return false;
- }
- else
- {
- Out << "STARTING SERVER(pid:" << server->pid() << "): " << server->running();
- }
-
- construct.push_server(server);
-
- if (default_port() == 0)
- {
- assert(server->has_port());
- set_default_port(server->port());
- }
-
- Outn();
-
- return true;
-}
-
-bool server_startup_st::start_socket_server(const std::string& server_type, const in_port_t try_port, int argc, const char *argv[])
-{
- (void)try_port;
- Outn();
-
- Server *server= NULL;
- if (0)
- { }
- else if (server_type.compare("gearmand") == 0)
- {
- Error << "Socket files are not supported for gearmand yet";
- }
- else if (server_type.compare("memcached-sasl") == 0)
- {
- if (MEMCACHED_SASL_BINARY)
- {
- if (HAVE_LIBMEMCACHED)
- {
- server= build_memcached_sasl_socket("localhost", try_port, username(), password());
- }
- else
- {
- Error << "Libmemcached was not found";
- }
- }
- else
- {
- Error << "No memcached binary is available";
- }
- }
- else if (server_type.compare("memcached") == 0)
- {
- if (MEMCACHED_BINARY)
- {
- if (HAVE_LIBMEMCACHED)
- {
- server= build_memcached_socket("localhost", try_port);
- }
- else
- {
- Error << "Libmemcached was not found";
- }
- }
- else
- {
- Error << "No memcached binary is available";
- }
- }
- else
- {
- Error << "Failed to start " << server_type << ", no support was found to be compiled in for it.";
- }
-
- if (server == NULL)
- {
- Error << "Failure occured while creating server: " << server_type;
- return false;
- }
-
- /*
- We will now cycle the server we have created.
- */
- if (not server->cycle())
- {
- Error << "Could not start up server " << *server;
- delete server;
- return false;
- }
-
- server->build(argc, argv);
-
- if (is_debug())
- {
- Out << "Pausing for startup, hit return when ready.";
- std::string gdb_command= server->base_command();
- std::string options;
- Out << "run " << server->args(options);
- getchar();
- }
- else if (not server->start())
- {
- Error << "Failed to start " << *server;
- delete server;
- return false;
- }
- else
- {
- Out << "STARTING SERVER(pid:" << server->pid() << "): " << server->running();
- }
-
- push_server(server);
-
- set_default_socket(server->socket().c_str());
-
- Outn();
-
- return true;
-}
-
} // namespace libtest
return (_pid > 1);
}
+ bool wait_for_pidfile() const;
+
bool check_pid(pid_t pid_arg) const
{
return (pid_arg > 1);
std::ostream& operator<<(std::ostream& output, const libtest::Server &arg);
-class server_startup_st
-{
-private:
- std::string server_list;
- bool _socket;
- bool _sasl;
- std::string _username;
- std::string _password;
-
-public:
-
- uint8_t udp;
- std::vector<Server *> servers;
-
- server_startup_st() :
- _socket(false),
- _sasl(false),
- udp(0)
- { }
-
- bool start_socket_server(const std::string& server_type, const in_port_t try_port, int argc, const char *argv[]);
-
- std::string option_string() const;
-
- size_t count() const
- {
- return servers.size();
- }
-
- const std::string& password() const
- {
- return _password;
- }
-
- const std::string& username() const
- {
- return _username;
- }
-
-
- bool is_debug() const;
- bool is_helgrind() const;
- bool is_valgrind() const;
-
- bool socket()
- {
- return _socket;
- }
-
- bool sasl()
- {
- return _sasl;
- }
-
- void set_socket()
- {
- _socket= true;
- }
-
- void set_sasl(const std::string& username_arg, const std::string& password_arg)
- {
- _sasl= true;
- _username= username_arg;
- _password= password_arg;
- }
-
-
- void shutdown(bool remove= false);
- void push_server(Server *);
- Server *pop_server();
-
- ~server_startup_st();
-};
-
-bool server_startup(server_startup_st&, const std::string&, in_port_t try_port, int argc, const char *argv[]);
-
} // namespace libtest
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <libtest/common.h>
+
+#include <cassert>
+#include <cerrno>
+#include <cstdlib>
+#include <iostream>
+
+#include <algorithm>
+#include <functional>
+#include <locale>
+
+// trim from end
+static inline std::string &rtrim(std::string &s)
+{
+ s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
+ return s;
+}
+
+namespace libtest {
+
+void server_startup_st::push_server(Server *arg)
+{
+ servers.push_back(arg);
+
+ char port_str[NI_MAXSERV];
+ snprintf(port_str, sizeof(port_str), "%u", int(arg->port()));
+
+ std::string server_config_string;
+ if (arg->has_socket())
+ {
+ server_config_string+= "--socket=";
+ server_config_string+= '"';
+ server_config_string+= arg->socket();
+ server_config_string+= '"';
+ server_config_string+= " ";
+ }
+ else
+ {
+ server_config_string+= "--server=";
+ server_config_string+= arg->hostname();
+ server_config_string+= ":";
+ server_config_string+= port_str;
+ server_config_string+= " ";
+ }
+
+ server_list+= server_config_string;
+
+}
+
+Server* server_startup_st::pop_server()
+{
+ Server *tmp= servers.back();
+ servers.pop_back();
+ return tmp;
+}
+
+bool server_startup_st::shutdown(uint32_t number_of_host)
+{
+ assert(servers.size() > number_of_host);
+ if (servers.size() > number_of_host)
+ {
+ Server* tmp= servers[number_of_host];
+
+ if (tmp and tmp->has_pid() and not tmp->kill(tmp->pid()))
+ { }
+ else
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void server_startup_st::shutdown_and_remove()
+{
+ for (std::vector<Server *>::iterator iter= servers.begin(); iter != servers.end(); iter++)
+ {
+ delete *iter;
+ }
+ servers.clear();
+}
+
+void server_startup_st::shutdown()
+{
+ for (std::vector<Server *>::iterator iter= servers.begin(); iter != servers.end(); iter++)
+ {
+ if ((*iter)->has_pid() and not (*iter)->kill((*iter)->pid()))
+ {
+ Error << "Unable to kill:" << *(*iter);
+ }
+ }
+}
+
+void server_startup_st::restart()
+{
+ for (std::vector<Server *>::iterator iter= servers.begin(); iter != servers.end(); iter++)
+ {
+ (*iter)->start();
+ }
+}
+
+server_startup_st::~server_startup_st()
+{
+ shutdown_and_remove();
+}
+
+bool server_startup_st::is_debug() const
+{
+ return bool(getenv("LIBTEST_MANUAL_GDB"));
+}
+
+bool server_startup_st::is_valgrind() const
+{
+ return bool(getenv("LIBTEST_MANUAL_VALGRIND"));
+}
+
+bool server_startup_st::is_helgrind() const
+{
+ return bool(getenv("LIBTEST_MANUAL_HELGRIND"));
+}
+
+
+bool server_startup(server_startup_st& construct, const std::string& server_type, in_port_t try_port, int argc, const char *argv[])
+{
+ Outn();
+ (void)try_port;
+
+ set_max_port(try_port);
+
+ // Look to see if we are being provided ports to use
+ {
+ char variable_buffer[1024];
+ snprintf(variable_buffer, sizeof(variable_buffer), "LIBTEST_PORT_%lu", (unsigned long)construct.count());
+
+ char *var;
+ if ((var= getenv(variable_buffer)))
+ {
+ in_port_t tmp= in_port_t(atoi(var));
+
+ if (tmp > 0)
+ try_port= tmp;
+ }
+ }
+
+ libtest::Server *server= NULL;
+ if (0)
+ { }
+ else if (server_type.compare("gearmand") == 0)
+ {
+ if (GEARMAND_BINARY)
+ {
+ if (HAVE_LIBGEARMAN)
+ {
+ server= build_gearmand("localhost", try_port);
+ }
+ else
+ {
+ Error << "Libgearman was not found";
+ }
+ }
+ else
+ {
+ Error << "No gearmand binary is available";
+ }
+ }
+ else if (server_type.compare("blobslap_worker") == 0)
+ {
+ if (GEARMAND_BINARY and GEARMAND_BLOBSLAP_WORKER)
+ {
+ if (HAVE_LIBGEARMAN)
+ {
+ server= build_blobslap_worker(try_port);
+ }
+ else
+ {
+ Error << "Libgearman was not found";
+ }
+ }
+ else
+ {
+ Error << "No gearmand binary is available";
+ }
+ }
+ else if (server_type.compare("memcached-sasl") == 0)
+ {
+ if (MEMCACHED_SASL_BINARY)
+ {
+ if (HAVE_LIBMEMCACHED)
+ {
+ server= build_memcached_sasl("localhost", try_port, construct.username(), construct.password());
+ }
+ else
+ {
+ Error << "Libmemcached was not found";
+ }
+ }
+ else
+ {
+ Error << "No memcached binary that was compiled with sasl is available";
+ }
+ }
+ else if (server_type.compare("memcached") == 0)
+ {
+ if (MEMCACHED_BINARY)
+ {
+ if (HAVE_LIBMEMCACHED)
+ {
+ server= build_memcached("localhost", try_port);
+ }
+ else
+ {
+ Error << "Libmemcached was not found";
+ }
+ }
+ else
+ {
+ Error << "No memcached binary is available";
+ }
+ }
+ else
+ {
+ Error << "Failed to start " << server_type << ", no support was found to be compiled in for it.";
+ }
+
+ if (server == NULL)
+ {
+ Error << "Failure occured while creating server: " << server_type;
+ return false;
+ }
+
+ /*
+ We will now cycle the server we have created.
+ */
+ if (not server->cycle())
+ {
+ Error << "Could not start up server " << *server;
+ delete server;
+ return false;
+ }
+
+ server->build(argc, argv);
+
+ if (construct.is_debug())
+ {
+ Out << "Pausing for startup, hit return when ready.";
+ std::string gdb_command= server->base_command();
+ std::string options;
+ Out << "run " << server->args(options);
+ getchar();
+ }
+ else if (not server->start())
+ {
+ Error << "Failed to start " << *server;
+ delete server;
+ return false;
+ }
+ else
+ {
+ Out << "STARTING SERVER(pid:" << server->pid() << "): " << server->running();
+ }
+
+ construct.push_server(server);
+
+ if (default_port() == 0)
+ {
+ assert(server->has_port());
+ set_default_port(server->port());
+ }
+
+ Outn();
+
+ return true;
+}
+
+bool server_startup_st::start_socket_server(const std::string& server_type, const in_port_t try_port, int argc, const char *argv[])
+{
+ (void)try_port;
+ Outn();
+
+ Server *server= NULL;
+ if (0)
+ { }
+ else if (server_type.compare("gearmand") == 0)
+ {
+ Error << "Socket files are not supported for gearmand yet";
+ }
+ else if (server_type.compare("memcached-sasl") == 0)
+ {
+ if (MEMCACHED_SASL_BINARY)
+ {
+ if (HAVE_LIBMEMCACHED)
+ {
+ server= build_memcached_sasl_socket("localhost", try_port, username(), password());
+ }
+ else
+ {
+ Error << "Libmemcached was not found";
+ }
+ }
+ else
+ {
+ Error << "No memcached binary is available";
+ }
+ }
+ else if (server_type.compare("memcached") == 0)
+ {
+ if (MEMCACHED_BINARY)
+ {
+ if (HAVE_LIBMEMCACHED)
+ {
+ server= build_memcached_socket("localhost", try_port);
+ }
+ else
+ {
+ Error << "Libmemcached was not found";
+ }
+ }
+ else
+ {
+ Error << "No memcached binary is available";
+ }
+ }
+ else
+ {
+ Error << "Failed to start " << server_type << ", no support was found to be compiled in for it.";
+ }
+
+ if (server == NULL)
+ {
+ Error << "Failure occured while creating server: " << server_type;
+ return false;
+ }
+
+ /*
+ We will now cycle the server we have created.
+ */
+ if (not server->cycle())
+ {
+ Error << "Could not start up server " << *server;
+ delete server;
+ return false;
+ }
+
+ server->build(argc, argv);
+
+ if (is_debug())
+ {
+ Out << "Pausing for startup, hit return when ready.";
+ std::string gdb_command= server->base_command();
+ std::string options;
+ Out << "run " << server->args(options);
+ getchar();
+ }
+ else if (not server->start())
+ {
+ Error << "Failed to start " << *server;
+ delete server;
+ return false;
+ }
+ else
+ {
+ Out << "STARTING SERVER(pid:" << server->pid() << "): " << server->running();
+ }
+
+ push_server(server);
+
+ set_default_socket(server->socket().c_str());
+
+ Outn();
+
+ return true;
+}
+
+std::string server_startup_st::option_string() const
+{
+ std::string temp= server_list;
+ rtrim(temp);
+ return temp;
+}
+
+
+} // namespace libtest
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+#include <cassert>
+#include <cstdio>
+#include <cstring>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <string>
+#include <unistd.h>
+#include <vector>
+
+namespace libtest {
+
+class server_startup_st
+{
+private:
+ std::string server_list;
+ bool _socket;
+ bool _sasl;
+ uint32_t _count;
+ std::string _username;
+ std::string _password;
+
+public:
+
+ uint8_t udp;
+ std::vector<Server *> servers;
+
+ server_startup_st() :
+ _socket(false),
+ _sasl(false),
+ _count(5),
+ udp(0)
+ { }
+
+ bool start_socket_server(const std::string& server_type, const in_port_t try_port, int argc, const char *argv[]);
+
+ uint32_t count() const
+ {
+ return _count;
+ }
+
+ void set_count(uint32_t arg)
+ {
+ _count= arg;
+ }
+
+ void restart();
+
+ std::string option_string() const;
+
+ const std::string& password() const
+ {
+ return _password;
+ }
+
+ const std::string& username() const
+ {
+ return _username;
+ }
+
+
+ bool is_debug() const;
+ bool is_helgrind() const;
+ bool is_valgrind() const;
+
+ bool socket()
+ {
+ return _socket;
+ }
+
+ bool sasl()
+ {
+ return _sasl;
+ }
+
+ void set_socket()
+ {
+ _socket= true;
+ }
+
+ void set_sasl(const std::string& username_arg, const std::string& password_arg)
+ {
+ _sasl= true;
+ _username= username_arg;
+ _password= password_arg;
+ }
+
+
+ void shutdown_and_remove();
+ void shutdown();
+ bool shutdown(uint32_t number_of_host);
+
+ void push_server(Server *);
+ Server *pop_server();
+
+ ~server_startup_st();
+};
+
+bool server_startup(server_startup_st&, const std::string&, in_port_t try_port, int argc, const char *argv[]);
+
+} // namespace libtest
#include <pthread.h>
#include <semaphore.h>
+#include <signal.h>
enum shutdown_t {
SHUTDOWN_RUNNING,
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <libtest/common.h>
+
+static char global_socket[1024];
+
+namespace libtest {
+
+const char *default_socket()
+{
+ assert(global_socket[0]);
+ return global_socket;
+}
+
+void set_default_socket(const char *socket)
+{
+ if (socket)
+ {
+ strncpy(global_socket, socket, strlen(socket));
+ }
+}
+
+}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+namespace libtest {
+
+const char *default_socket();
+
+void set_default_socket(const char *socket);
+
+} // namespace libtest
+
#pragma once
+
struct Stats {
int32_t collection_success;
int32_t collection_skipped;
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <libtest/common.h>
+
+namespace libtest {
+
+const char *test_strerror(test_return_t code)
+{
+ switch (code) {
+ case TEST_SUCCESS:
+ return "ok";
+
+ case TEST_FAILURE:
+ return "failed";
+
+ case TEST_MEMORY_ALLOCATION_FAILURE:
+ return "memory allocation";
+
+ case TEST_SKIPPED:
+ return "skipped";
+
+ case TEST_FATAL:
+ break;
+ }
+
+ return "failed";
+}
+
+} // namespace libtest
#pragma once
+namespace libtest {
+
/**
@note Friendly print function for errors.
*/
LIBTEST_API
const char *test_strerror(test_return_t code);
+
+} // namespace libtest
#include <signal.h>
-#include <libtest/stats.h>
-#include <libtest/signal.h>
-
#ifndef __INTEL_COMPILER
#pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
using namespace libtest;
-static in_port_t global_port= 0;
-static char global_socket[1024];
-
-in_port_t default_port()
-{
- return global_port;
-}
-
-void set_default_port(in_port_t port)
-{
- global_port= port;
-}
-
-const char *default_socket()
-{
- assert(global_socket[0]);
- return global_socket;
-}
-
-bool test_is_local()
-{
- return (getenv("LIBTEST_LOCAL"));
-}
-
-void set_default_socket(const char *socket)
-{
- if (socket)
- {
- strncpy(global_socket, socket, strlen(socket));
- }
-}
-
static void stats_print(Stats *stats)
{
if (stats->collection_failed == 0 and stats->collection_success == 0)
return s + us;
}
-const char *test_strerror(test_return_t code)
-{
- switch (code) {
- case TEST_SUCCESS:
- return "ok";
-
- case TEST_FAILURE:
- return "failed";
-
- case TEST_MEMORY_ALLOCATION_FAILURE:
- return "memory allocation";
-
- case TEST_SKIPPED:
- return "skipped";
-
- case TEST_FATAL:
- break;
- }
-
- return "failed";
-}
-
-void create_core(void)
-{
- if (getenv("LIBMEMCACHED_NO_COREDUMP") == NULL)
- {
- pid_t pid= fork();
-
- if (pid == 0)
- {
- abort();
- }
- else
- {
- while (waitpid(pid, NULL, 0) != pid) {};
- }
- }
-}
-
static Framework *world= NULL;
int main(int argc, char *argv[])
{
world= new Framework();
- if (not world)
+ if (world == NULL)
{
Error << "Failed to create Framework()";
return EXIT_FAILURE;
#pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
-#include <libtest/stream.h>
-#include <libtest/comparison.hpp>
-
/**
A structure describing the test case.
*/
fprintf(stderr, "\n%s:%d: Assertion failed for %s: ", __FILE__, __LINE__, __func__);\
perror(#A); \
fprintf(stderr, "\n"); \
- create_core(); \
+ libtest::create_core(); \
assert((A)); \
} \
} while (0)
if ((A)) { \
fprintf(stderr, "\n%s:%d: Assertion failed %s, with message %s, in %s", __FILE__, __LINE__, (B), #A, __func__ );\
fprintf(stderr, "\n"); \
- create_core(); \
+ libtest::create_core(); \
assert((A)); \
} \
} while (0)
{ \
if (! (A)) { \
fprintf(stderr, "\n%s:%d: Assertion \"%s\" failed, in %s\n", __FILE__, __LINE__, #A, __func__);\
- create_core(); \
+ libtest::create_core(); \
return TEST_FAILURE; \
} \
} while (0)
{ \
if (! (A)) { \
fprintf(stderr, "\n%s:%d: Assertion \"%s\" failed, in %s\n", __FILE__, __LINE__, #A, __func__);\
- create_core(); \
+ libtest::create_core(); \
return TEST_FAILURE; \
} \
} while (0)
#define test_true_got(__expected, __hint) \
do \
{ \
- if (not libtest::_compare_true_hint(__FILE__, __LINE__, __func__, ((__expected)), #__expected, ((__hint)))) \
+ if (not libtest::_compare_truth_hint(__FILE__, __LINE__, __func__, ((__expected)), #__expected, ((__hint)))) \
{ \
- create_core(); \
+ libtest::create_core(); \
return TEST_FAILURE; \
} \
} while (0)
{ \
if (1) { \
fprintf(stderr, "\n%s:%d: Failed with %s, in %s\n", __FILE__, __LINE__, #A, __func__);\
- create_core(); \
+ libtest::create_core(); \
return TEST_FAILURE; \
} \
} while (0)
{ \
if ((A)) { \
fprintf(stderr, "\n%s:%d: Assertion failed %s, in %s\n", __FILE__, __LINE__, #A, __func__);\
- create_core(); \
+ libtest::create_core(); \
return TEST_FAILURE; \
} \
} while (0)
{ \
if ((A)) { \
fprintf(stderr, "\n%s:%d: Assertion failed %s with %s\n", __FILE__, __LINE__, #A, (B));\
- create_core(); \
+ libtest::create_core(); \
return TEST_FAILURE; \
} \
} while (0)
{ \
if (not libtest::_compare(__FILE__, __LINE__, __func__, ((__expected)), ((__actual)))) \
{ \
- create_core(); \
+ libtest::create_core(); \
return TEST_FAILURE; \
} \
} while (0)
{ \
if (not libtest::_compare_zero(__FILE__, __LINE__, __func__, ((__actual)))) \
{ \
- create_core(); \
+ libtest::create_core(); \
return TEST_FAILURE; \
} \
} while (0)
{ \
if (not libtest::_compare_hint(__FILE__, __LINE__, __func__, (__expected), (__actual), (__hint))) \
{ \
- create_core(); \
+ libtest::create_core(); \
return TEST_FAILURE; \
} \
} while (0)
+#define test_compare_warn(__expected, __actual) \
+do \
+{ \
+ void(libtest::_compare(__FILE__, __LINE__, __func__, (__expected), (__actual))); \
+} while (0)
+
+#define test_compare_warn_hint(__expected, __actual, __hint) \
+do \
+{ \
+ libtest::_compare_hint(__FILE__, __LINE__, __func__, (__expected), (__actual), (__hint)); \
+} while (0)
+
+#define test_warn(__truth) \
+do \
+{ \
+ void(libtest::_truth(__FILE__, __LINE__, __func__, (__truth))); \
+} while (0)
+
+#define test_warn_hint(__truth, __hint) \
+do \
+{ \
+ void(libtest::_compare_truth_hint(__FILE__, __LINE__, __func__, (__truth), #__truth, (__hint))); \
+} while (0)
+
#define test_strcmp(A,B) \
do \
if (strcmp((A), (B))) \
{ \
fprintf(stderr, "\n%s:%d: Expected %s, got %s\n", __FILE__, __LINE__, (A), (B)); \
- create_core(); \
+ libtest::create_core(); \
return TEST_FAILURE; \
} \
} while (0)
if (memcmp((A), (B), (C))) \
{ \
fprintf(stderr, "\n%s:%d: %.*s -> %.*s\n", __FILE__, __LINE__, (int)(C), (char *)(A), (int)(C), (char *)(B)); \
- create_core(); \
+ libtest::create_core(); \
return TEST_FAILURE; \
} \
} while (0)
#include <libtest/version.h>
#include <libtest/error.h>
+#include <libtest/strerror.h>
+#include <libtest/stream.h>
+#include <libtest/comparison.hpp>
#include <libtest/server.h>
+#include <libtest/server_container.h>
#include <libtest/wait.h>
#include <libtest/callbacks.h>
#include <libtest/test.h>
-#include <libtest/strerror.h>
#include <libtest/core.h>
#include <libtest/runner.h>
+#include <libtest/port.h>
+#include <libtest/is_local.hpp>
+#include <libtest/socket.hpp>
#include <libtest/stats.h>
#include <libtest/collection.h>
#include <libtest/framework.h>
#include <libtest/stream.h>
#include <libtest/cmdline.h>
#include <libtest/string.hpp>
-
-#pragma once
-
-LIBTEST_API
-in_port_t default_port();
-
-LIBTEST_API
-void set_default_port(in_port_t port);
-
-LIBTEST_API
-const char* default_socket();
-
-LIBTEST_API
-void set_default_socket(const char *socket);
-
-LIBTEST_API
-bool test_is_local(void);
+#include <libtest/binaries.h>
#include <libtest/test.hpp>
+#if defined(LIBTEST_WITH_LIBMEMCACHED_SUPPORT) && LIBTEST_WITH_LIBMEMCACHED_SUPPORT
+#include <libmemcached/memcached.h>
+#endif
+
+#if defined(LIBTEST_WITH_LIBGEARMAN_SUPPORT) && LIBTEST_WITH_LIBGEARMAN_SUPPORT
+#include <libgearman/gearman.h>
+#endif
+
#include <cstdlib>
#include <unistd.h>
return TEST_SUCCESS;
}
+static test_return_t test_success_equals_one_test(void *)
+{
+ test_skip(HAVE_LIBMEMCACHED, true);
+#if defined(HAVE_LIBMEMCACHED) && HAVE_LIBMEMCACHED
+ test_zero(MEMCACHED_SUCCESS);
+#endif
+ return TEST_SUCCESS;
+}
+
static test_return_t test_success_test(void *)
{
return TEST_SUCCESS;
return TEST_SUCCESS;
}
+static test_return_t _compare_test_return_t_test(void *)
+{
+ test_compare(TEST_SUCCESS, TEST_SUCCESS);
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t _compare_memcached_return_t_test(void *)
+{
+ test_skip(HAVE_LIBMEMCACHED, true);
+#if defined(HAVE_LIBMEMCACHED) && HAVE_LIBMEMCACHED
+ test_compare(MEMCACHED_SUCCESS, MEMCACHED_SUCCESS);
+#endif
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t _compare_gearman_return_t_test(void *)
+{
+ test_skip(HAVE_LIBGEARMAN, true);
+#if defined(HAVE_LIBGEARMAN) && HAVE_LIBGEARMAN
+ test_compare(GEARMAN_SUCCESS, GEARMAN_SUCCESS);
+#endif
+
+ return TEST_SUCCESS;
+}
+
static test_return_t gearmand_cycle_test(void *object)
{
server_startup_st *servers= (server_startup_st*)object;
test_true(servers);
- if (HAVE_LIBGEARMAN)
+ if (HAVE_LIBGEARMAN and GEARMAND_BINARY)
{
+ test_true(has_gearmand_binary());
const char *argv[1]= { "cycle_gearmand" };
test_true(server_startup(*servers, "gearmand", 9999, 1, argv));
if (MEMCACHED_BINARY and HAVE_LIBMEMCACHED)
{
+ test_true(has_memcached_binary());
const char *argv[1]= { "cycle_memcached" };
test_true(server_startup(*servers, "memcached", 9998, 1, argv));
if (MEMCACHED_BINARY and HAVE_LIBMEMCACHED)
{
+ test_true(has_memcached_binary());
const char *argv[1]= { "cycle_memcached" };
test_true(servers->start_socket_server("memcached", 9997, 1, argv));
return TEST_SKIPPED;
}
+static test_return_t memcached_sasl_test(void *object)
+{
+ server_startup_st *servers= (server_startup_st*)object;
+ test_true(servers);
+
+ if (getenv("TESTS_ENVIRONMENT"))
+ {
+ return TEST_SKIPPED;
+ }
+
+ if (MEMCACHED_SASL_BINARY and HAVE_LIBMEMCACHED)
+ {
+ test_true(has_memcached_sasl_binary());
+ const char *argv[1]= { "cycle_memcached_sasl" };
+ test_true(server_startup(*servers, "memcached-sasl", 9996, 1, argv));
+
+ return TEST_SUCCESS;
+ }
+
+ return TEST_SKIPPED;
+}
+
test_st gearmand_tests[] ={
#if 0
{"pause", 0, pause_test },
test_st memcached_tests[] ={
{"memcached startup-shutdown", 0, memcached_cycle_test },
{"memcached(socket file) startup-shutdown", 0, memcached_socket_cycle_test },
+ {"memcached_sasl() startup-shutdown", 0, memcached_sasl_test },
{0, 0, 0}
};
};
test_st tests_log[] ={
- {"TEST_SUCCESS", 0, test_success_test },
- {"TEST_FAILURE", 0, test_failure_test },
+ {"TEST_SUCCESS", false, test_success_test },
+ {"TEST_FAILURE", false, test_failure_test },
+ {"TEST_SUCCESS == 0", false, test_success_equals_one_test },
{0, 0, 0}
};
{0, 0, 0}
};
+test_st comparison_tests[] ={
+ {"_compare(test_return_t)", 0, _compare_test_return_t_test },
+ {"_compare(memcached_return_t)", 0, _compare_memcached_return_t_test },
+ {"_compare(gearman_return_t)", 0, _compare_gearman_return_t_test },
+ {0, 0, 0}
+};
+
collection_st collection[] ={
{"environment", 0, 0, environment_tests},
{"return values", 0, 0, tests_log},
{"local", 0, 0, local_log},
{"directories", 0, 0, directories_tests},
+ {"comparison", 0, 0, comparison_tests},
{"gearmand", 0, 0, gearmand_tests},
{"memcached", 0, 0, memcached_tests},
{0, 0, 0, 0}
#pragma once
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LIBTEST@_WITH_LIBMEMCACHED_SUPPORT@
-#define LIBTEST@_WITH_LIBGEARMAN_SUPPORT@
-
#define LIBTEST_VERSION_STRING "@VERSION@"
#define LIBTEST_VERSION_HEX @HEX_VERSION@
-
-#ifdef __cplusplus
-}
-#endif
#pragma once
#if defined(BUILDING_LIBTEST)
-# if defined(HAVE_VISIBILITY)
+# if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
# define LIBTEST_API __attribute__ ((visibility("default")))
-# define LIBTEST_INTERNAL_API __attribute__ ((visibility("hidden")))
-# define LIBTEST_API_DEPRECATED __attribute__ ((deprecated,visibility("default")))
-# define LIBTEST_LOCAL __attribute__ ((visibility("hidden")))
+# define LIBTEST_LOCAL __attribute__ ((visibility("default")))
# elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550)
# define LIBTEST_API __global
-# define LIBTEST_INTERNAL_API __hidden
-# define LIBTEST_API_DEPRECATED __global
-# define LIBTEST_LOCAL __hidden
+# define LIBTEST_LOCAL __global
# elif defined(_MSC_VER)
-# define LIBTEST_API extern __declspec(dllexport)
-# define LIBTEST_INTERNAL_API extern __declspec(dllexport)
-# define LIBTEST_DEPRECATED_API extern __declspec(dllexport)
-# define LIBTEST_LOCAL
-# endif /* defined(HAVE_VISIBILITY) */
-#else /* defined(BUILDING_LIBTEST) */
-# if defined(_MSC_VER)
-# define LIBTEST_API extern __declspec(dllimport)
-# define LIBTEST_INTERNAL_API extern __declspec(dllimport)
-# define LIBTEST_API_DEPRECATED extern __declspec(dllimport)
-# define LIBTEST_LOCAL
+# define LIBTEST_API extern __declspec(dllexport)
+# define LIBTEST_LOCAL extern __declspec(dllexport)
# else
# define LIBTEST_API
-# define LIBTEST_INTERNAL_API
-# define LIBTEST_API_DEPRECATED
# define LIBTEST_LOCAL
-# endif /* defined(_MSC_VER) */
-#endif /* defined(BUILDING_LIBTEST) */
+# endif
+#else
+# if defined(BUILDING_LIBTEST)
+# if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
+# define LIBTEST_API __attribute__ ((visibility("default")))
+# define LIBTEST_LOCAL __attribute__ ((visibility("hidden")))
+# elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550)
+# define LIBTEST_API __global
+# define LIBTEST_LOCAL __hidden
+# elif defined(_MSC_VER)
+# define LIBTEST_API extern __declspec(dllexport)
+# define LIBTEST_LOCAL
+# else
+# define LIBTEST_API
+# define LIBTEST_LOCAL
+# endif /* defined(HAVE_VISIBILITY) */
+# else /* defined(BUILDING_LIBTEST) */
+# if defined(_MSC_VER)
+# define LIBTEST_API extern __declspec(dllimport)
+# define LIBTEST_LOCAL
+# else
+# define LIBTEST_API
+# define LIBTEST_LOCAL
+# endif /* defined(_MSC_VER) */
+# endif /* defined(BUILDING_LIBTEST) */
+#endif /* defined(BUILDING_LIBTESTINTERNAL) */
uint32_t this_wait;
uint32_t retry;
+ if (filename.empty())
+ {
+ _successful= false;
+ return;
+ }
+
for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
{
if (access(filename.c_str(), R_OK) == 0)
--- /dev/null
+AX_WITH_PROG(GEARMAND_BINARY,gearmand)
+AS_IF([test -f "$ac_cv_path_GEARMAND_BINARY"],
+ [
+ AC_DEFINE([HAVE_GEARMAND_BINARY], [1], [If Gearmand binary is available])
+ AC_DEFINE_UNQUOTED([GEARMAND_BINARY], "$ac_cv_path_GEARMAND_BINARY", [Name of the gearmand binary used in make test])
+ ],
+ [
+ AC_DEFINE([HAVE_GEARMAND_BINARY], [0], [If Gearmand binary is available])
+ AC_DEFINE([GEARMAND_BINARY], [0], [Name of the gearmand binary used in make test])
+ ])
+
AX_WITH_PROG(MEMCACHED_BINARY,memcached)
AS_IF([test -f "$ac_cv_path_MEMCACHED_BINARY"],
[
+ AC_DEFINE([HAVE_MEMCACHED_BINARY], [1], [If Memcached binary is available])
AC_DEFINE_UNQUOTED([MEMCACHED_BINARY], "$ac_cv_path_MEMCACHED_BINARY", [Name of the memcached binary used in make test])
],
[
+ AC_DEFINE([HAVE_MEMCACHED_BINARY], [0], [If Memcached binary is available])
AC_DEFINE([MEMCACHED_BINARY], [0], [Name of the memcached binary used in make test])
])
AX_WITH_PROG(MEMCACHED_SASL_BINARY,memcached_sasl)
AS_IF([test -f "$ac_cv_path_MEMCACHED_SASL_BINARY"],
[
+ AC_DEFINE([HAVE_MEMCACHED_SASL_BINARY], [1], [Name of the memcached_sasl binary used in make test])
AC_DEFINE_UNQUOTED([MEMCACHED_SASL_BINARY], "$ac_cv_path_MEMCACHED_SASL_BINARY", [Name of the memcached_sasl binary used in make test])
],
[
+ AC_DEFINE([HAVE_MEMCACHED_SASL_BINARY], [0], [Name of the memcached_sasl binary used in make test])
AC_DEFINE([MEMCACHED_SASL_BINARY], [0], [Name of the memcached_sasl binary used in make test])
])
AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"],
[CXXFLAGS=""])
- m4_if(PCT_DONT_SUPRESS_INCLUDE,yes,[
- AM_INIT_AUTOMAKE(-Wall -Werror -Wno-portability subdir-objects foreign tar-ustar)
- ],[
- AM_INIT_AUTOMAKE(-Wall -Werror -Wno-portability nostdinc subdir-objects foreign tar-ustar)
- ])
+ AM_INIT_AUTOMAKE(-Wall -Werror -Wno-portability subdir-objects foreign tar-ustar)
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
PANDORA_PLATFORM
- PANDORA_LIBTOOL
-
dnl autoconf doesn't automatically provide a fail-if-no-C++ macro
dnl so we check c++98 features and fail if we don't have them, mainly
dnl for that reason
PANDORA_HAVE_GCC_ATOMICS
- m4_if(PCT_USE_VISIBILITY,[yes],[
- PANDORA_ENABLE_VISIBILITY
- ],[
- PANDORA_CHECK_VISIBILITY
- ])
-
PANDORA_HEADER_ASSERT
PANDORA_WARNINGS(PCT_ALL_ARGS)
+++ /dev/null
-dnl Copyright (C) 2009 Sun Microsystems, Inc.
-dnl This file is free software; Sun Microsystems, Inc.
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-AC_DEFUN([PANDORA_LIBTOOL],[
- AC_REQUIRE([AC_DISABLE_STATIC])
- AC_REQUIRE([AC_PROG_LIBTOOL])
- m4_ifndef([LT_PREREQ],[
- pandora_have_old_libtool=yes
- ],[
- pandora_have_old_libtool=no
- ])
- AS_IF([test "$SUNCC" = "yes" -a "${pandora_have_old_libtool}" = "yes"],[
- AC_MSG_ERROR([Building ${PACKAGE} with Sun Studio requires at least libtool 2.2])
- ])
-
- dnl By requiring AC_PROG_LIBTOOL, we should force the macro system to read
- dnl libtool.m4, where in 2.2 AC_PROG_LIBTOOL is an alias for LT_INIT
- dnl Then, if we're on 2.2, we should have LT_LANG, so we'll call it.
- m4_ifdef([LT_LANG],[
- LT_LANG(C)
- LT_LANG(C++)
- ])
-])
# Debugging. No optimization.
AM_CFLAGS="${AM_CFLAGS} ${DEBUG_CFLAGS} -DDEBUG"
AM_CXXFLAGS="${AM_CXXFLAGS} ${DEBUG_CXXFLAGS} -DDEBUG"
+ AC_DEFINE(DEBUG, [ 1 ], [Define to 1 to enable debugging code.])
],[
# Optimized version. No debug
AM_CFLAGS="${AM_CFLAGS} ${OPTIMIZE_CFLAGS}"
AM_CXXFLAGS="${AM_CXXFLAGS} ${OPTIMIZE_CXXFLAGS}"
+ AC_DEFINE(DEBUG, [ 0 ], [Define to 1 to enable debugging code.])
])
])
+++ /dev/null
-dnl Copyright (C) 2005, 2008 Free Software Foundation, Inc.
-dnl Copyright (C) 2009 Monty Taylor
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl From Bruno Haible.
-
-dnl Tests whether the compiler supports the command-line option
-dnl -fvisibility=hidden and the function and variable attributes
-dnl __attribute__((__visibility__("hidden"))) and
-dnl __attribute__((__visibility__("default"))).
-dnl Does *not* test for __visibility__("protected") - which has tricky
-dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on
-dnl MacOS X.
-dnl Does *not* test for __visibility__("internal") - which has processor
-dnl dependent semantics.
-dnl Does *not* test for #pragma GCC visibility push(hidden) - which is
-dnl "really only recommended for legacy code".
-dnl Set the variable CFLAG_VISIBILITY.
-dnl Defines and sets the variable HAVE_VISIBILITY.
-
-AC_DEFUN([PANDORA_CHECK_VISIBILITY],
-[
- AC_REQUIRE([AC_PROG_CC])
- CFLAG_VISIBILITY=
- HAVE_VISIBILITY=0
- AS_IF([test -n "$GCC"],[
- AC_MSG_CHECKING([for simple visibility declarations])
- AC_CACHE_VAL([gl_cv_cc_visibility], [
- gl_save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -fvisibility=hidden -Werror"
- AC_TRY_COMPILE(
- [extern __attribute__((__visibility__("hidden"))) int hiddenvar;
- extern __attribute__((__visibility__("default"))) int exportedvar;
- extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void);
- extern __attribute__((__visibility__("default"))) int exportedfunc (void);],
- [],[
- case "$host_os" in
- *darwin*)
- gl_cv_cc_visibility=no
- ;;
- *)
- gl_cv_cc_visibility=yes
- ;;
- esac
- ],[gl_cv_cc_visibility=no])
- CFLAGS="$gl_save_CFLAGS"])
- AC_MSG_RESULT([$gl_cv_cc_visibility])
- if test $gl_cv_cc_visibility = yes; then
- CFLAG_VISIBILITY="-fvisibility=hidden"
- CXXFLAG_VISIBILITY="-fvisibility=hidden -fvisibility-inlines-hidden"
- NO_VISIBILITY="-fvisibility=default"
- HAVE_VISIBILITY=1
- fi
- ])
- AS_IF([test "x$SUNCC" = "xyes"],[
- CFLAG_VISIBILITY="-xldscope=hidden"
- CXXFLAG_VISIBILITY="-xldscope=hidden"
- NO_VISIBILITY="-xldscope=global"
- HAVE_VISIBILITY=1
- ])
- AC_SUBST([CFLAG_VISIBILITY])
- AC_SUBST([CXXFLAG_VISIBILITY])
- AC_SUBST([NO_VISIBILITY])
- AC_SUBST([HAVE_VISIBILITY])
- AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY],
- [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.])
-])
-
-AC_DEFUN([PANDORA_ENABLE_VISIBILITY],[
- AC_REQUIRE([PANDORA_CHECK_VISIBILITY])
- AM_CFLAGS="${AM_CFLAGS} ${CFLAG_VISIBILITY}"
- AM_CXXFLAGS="${AM_CXXFLAGS} ${CXXFLAG_VISIBILITY}"
-])
+++ /dev/null
-dnl Copyright (C) 2009 Sun Microsystems, Inc.
-dnl This file is free software; Sun Microsystems, Inc.
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-AC_DEFUN([_PANDORA_SEARCH_MEMCACHED],[
-
- AC_ARG_WITH([memcached],
- [AS_HELP_STRING([--with-memcached],
- [Memcached binary to use for make test])],
- [ac_cv_with_memcached="$withval"],
- [ac_cv_with_memcached=memcached])
-
- # just ignore the user if --without-memcached is passed.. it is
- # only used by make test
- AS_IF([test "x$ac_cv_with_memcached" = "xno"],[
- ac_cv_with_memcached=memcached
- MEMCACHED_BINARY=memcached
- ],[
- AS_IF([test -f "$ac_cv_with_memcached"],[
- MEMCACHED_BINARY=$ac_cv_with_memcached
- ],[
- AC_PATH_PROG([MEMCACHED_BINARY], [$ac_cv_with_memcached], "no")
- ])
- ])
- AC_DEFINE_UNQUOTED([MEMCACHED_BINARY], "$MEMCACHED_BINARY",
- [Name of the memcached binary used in make test])
- AM_CONDITIONAL([HAVE_MEMCACHED],[test "x$MEMCACHED_BINARY" != "xno"])
-])
-
-AC_DEFUN([PANDORA_HAVE_MEMCACHED],[
- AC_REQUIRE([_PANDORA_SEARCH_MEMCACHED])
-])
-
-AC_DEFUN([PANDORA_REQUIRE_MEMCACHED],[
- AC_REQUIRE([PANDORA_HAVE_MEMCACHED])
- AS_IF([test "x$MEMCACHED_BINARY" = "xno"],[
- AC_MSG_ERROR(["could not find memcached binary"])
- ])
-])
-
%{_mandir}/man3/memcached_stat.3.gz
%{_mandir}/man3/memcached_stat_execute.3.gz
%{_mandir}/man3/memcached_stat_get_keys.3.gz
+%{_mandir}/man3/memcached_last_error_message.3.gz
%{_mandir}/man3/memcached_stat_get_value.3.gz
%{_mandir}/man3/memcached_stat_servername.3.gz
%{_mandir}/man3/memcached_strerror.3.gz
#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT +10
-#define SERVERS_TO_CREATE 5
#include "libmemcached_world.h"
extern "C" {
#endif
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t basic_init_test(memcached_st *junk);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t basic_clone_test(memcached_st *memc);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t basic_reset_stack_test(memcached_st *junk);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t basic_reset_heap_test(memcached_st *junk);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t basic_reset_stack_clone_test(memcached_st *memc);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t basic_reset_heap_clone_test(memcached_st *memc);
#ifdef __cplusplus
#include <config.h>
#include <libtest/test.hpp>
-#include <libmemcached/common.h>
+#include <libmemcached/memcached.h>
#include <libmemcached/is.h>
#include <libmemcached/util.h>
}
-test_return_t confirm_keys_exist(memcached_st *memc, const char * const *keys, const size_t number_of_keys, bool key_matches_value)
+test_return_t confirm_keys_exist(memcached_st *memc, const char * const *keys, const size_t number_of_keys, bool key_matches_value, bool require_all)
{
for (size_t x= 0; x < number_of_keys; ++x)
{
test_string_make_from_cstr(keys[x]), // Keys
&value_length,
0, &rc);
- test_true_got(value, keys[x]);
- if (key_matches_value)
+ if (require_all)
{
- test_strcmp(keys[x], value);
+ test_true_got(value, keys[x]);
+ if (key_matches_value)
+ {
+ test_strcmp(keys[x], value);
+ }
+ }
+ else if (memcached_success(rc))
+ {
+ test_warn_hint(value, keys[x]);
+ if (value and key_matches_value)
+ {
+ test_strcmp(keys[x], value);
+ }
+ }
+
+ if (value)
+ {
+ free(value);
}
- free(value);
}
return TEST_SUCCESS;
#pragma once
-test_return_t confirm_keys_exist(memcached_st *memc, const char * const *keys, const size_t number_of_keys, bool key_matches_value= false);
+test_return_t confirm_keys_exist(memcached_st *memc, const char * const *keys, const size_t number_of_keys, bool key_matches_value= false, bool require_all= false);
test_return_t confirm_keys_dont_exist(memcached_st *memc, const char * const *keys, const size_t number_of_keys);
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached library
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * 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 <config.h>
+
+/*
+ C++ interface test
+*/
+#include <libmemcached/memcached.hpp>
+#include <libmemcached/server_instance.h>
+#include <libtest/test.hpp>
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <ctime>
+
+#include <string>
+#include <iostream>
+
+using namespace std;
+using namespace memcache;
+using namespace libtest;
+
+Framework *global_framework= NULL;
+
+static test_return_t shutdown_servers(memcached_st *memc)
+{
+ test_compare(memcached_server_count(memc), 1U);
+
+ // Disable a single server, just the first
+ global_framework->servers().shutdown(0);
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t add_shutdown_servers(memcached_st *memc)
+{
+ while (memcached_server_count(memc) < 2)
+ {
+ const char *argv[1]= { "add_shutdown_server" };
+ in_port_t port= max_port() +1;
+ test_true(global_framework->servers().start_socket_server("memcached", port, 1, argv));
+ test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "localhost", port));
+ }
+
+ // Disable a single server, just the first
+ global_framework->servers().shutdown(0);
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t restart_servers(memcached_st *)
+{
+ // Restart the servers
+ global_framework->servers().restart();
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t cull_TEST(memcached_st *memc)
+{
+ uint32_t count= memcached_server_count(memc);
+
+ // Do not do this in your code, it is not supported.
+ memc->servers[0].options.is_dead= true;
+ memc->state.is_time_for_rebuild= true;
+
+ uint32_t new_count= memcached_server_count(memc);
+ test_compare(count, new_count);
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t MEMCACHED_SERVER_TEMPORARILY_DISABLED_TEST(memcached_st *memc)
+{
+ test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 30));
+ test_compare_got(MEMCACHED_CONNECTION_FAILURE,
+ memcached_set(memc,
+ test_literal_param("foo"),
+ NULL, 0, time_t(0), uint32_t(0)),
+ memcached_last_error_message(memc));
+
+ /*
+ Setting server_failure_counter==0 should not influence the timeout that we set above,
+ since we check the timeout that is created by the failure before we check how many times
+ a server has failed.
+ */
+ test_compare(MEMCACHED_SERVER_TEMPORARILY_DISABLED,
+ memcached_set(memc, test_literal_param("foo"), NULL, 0, time_t(0), uint32_t(0)));
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t MEMCACHED_SERVER_TEMPORARILY_DISABLED_to_success_TEST(memcached_st *memc)
+{
+ test_compare_got(MEMCACHED_CONNECTION_FAILURE,
+ memcached_set(memc,
+ test_literal_param("foo"),
+ NULL, 0, time_t(0), uint32_t(0)),
+ memcached_last_error_message(memc));
+
+ /*
+ Setting server_failure_counter==0 should not influence the timeout that we set above,
+ since we check the timeout that is created by the failure before we check how many times
+ a server has failed.
+ */
+ test_compare(MEMCACHED_SERVER_TEMPORARILY_DISABLED,
+ memcached_set(memc, test_literal_param("foo"), NULL, 0, time_t(0), uint32_t(0)));
+
+ global_framework->servers().restart();
+
+ memcached_return_t ret;
+ do {
+ sleep(3);
+ ret= memcached_set(memc, test_literal_param("foo"), NULL, 0, time_t(0), uint32_t(0));
+ } while (ret == MEMCACHED_SERVER_TEMPORARILY_DISABLED);
+
+ test_compare_got(MEMCACHED_SUCCESS, ret, memcached_last_error_message(memc));
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t MEMCACHED_SERVER_MARKED_DEAD_TEST(memcached_st *memc)
+{
+ test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 30));
+ test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, true));
+
+ memcached_return_t ret;
+ do {
+ ret= memcached_set(memc,
+ test_literal_param("foo"),
+ NULL, 0, time_t(0), uint32_t(0));
+ } while (ret == MEMCACHED_SUCCESS or ret == MEMCACHED_CONNECTION_FAILURE);
+ test_compare(MEMCACHED_SERVER_TEMPORARILY_DISABLED, ret);
+
+ do {
+ sleep(3);
+ ret= memcached_set(memc, test_literal_param("foo"), NULL, 0, time_t(0), uint32_t(0));
+ } while (ret == MEMCACHED_SERVER_TEMPORARILY_DISABLED or ret == MEMCACHED_SUCCESS);
+
+ test_compare_got(MEMCACHED_SERVER_MARKED_DEAD, ret, memcached_last_error_message(memc));
+
+ return TEST_SUCCESS;
+}
+
+test_st cull_TESTS[] ={
+ { "cull servers", true, (test_callback_fn*)cull_TEST },
+ { 0, 0, 0 }
+};
+
+test_st server_temporarily_disabled_TESTS[] ={
+ { "memcached_set(MEMCACHED_SERVER_TEMPORARILY_DISABLED)", true, (test_callback_fn*)MEMCACHED_SERVER_TEMPORARILY_DISABLED_TEST },
+ { "memcached_set(MEMCACHED_SERVER_TEMPORARILY_DISABLED -> MEMCACHED_SUCCESS)", true, (test_callback_fn*)MEMCACHED_SERVER_TEMPORARILY_DISABLED_to_success_TEST },
+ { 0, 0, 0 }
+};
+
+test_st server_permanently_disabled_TESTS[] ={
+ { "memcached_set(MEMCACHED_SERVER_MARKED_DEAD)", true, (test_callback_fn*)MEMCACHED_SERVER_MARKED_DEAD_TEST },
+ { 0, 0, 0 }
+};
+
+collection_st collection[] ={
+ { "cull", (test_callback_fn*)shutdown_servers, (test_callback_fn*)restart_servers, cull_TESTS },
+ { "server failed", (test_callback_fn*)shutdown_servers, (test_callback_fn*)restart_servers, server_temporarily_disabled_TESTS },
+ { "server eject", (test_callback_fn*)add_shutdown_servers, (test_callback_fn*)restart_servers, server_permanently_disabled_TESTS },
+ { 0, 0, 0, 0 }
+};
+
+#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT +10
+#include "libmemcached_world.h"
+
+void get_world(Framework *world)
+{
+ world->servers().set_count(1);
+
+ world->collections= collection;
+
+ world->_create= (test_callback_create_fn*)world_create;
+ world->_destroy= (test_callback_destroy_fn*)world_destroy;
+
+ world->item._startup= (test_callback_fn*)world_test_startup;
+ world->item.set_pre((test_callback_fn*)world_pre_run);
+ world->item.set_flush((test_callback_fn*)world_flush);
+ world->item.set_post((test_callback_fn*)world_post_run);
+ world->_on_error= (test_callback_error_fn*)world_on_error;
+
+ world->collection_startup= (test_callback_fn*)world_container_startup;
+ world->collection_shutdown= (test_callback_fn*)world_container_shutdown;
+
+ world->set_runner(&defualt_libmemcached_runner);
+
+ global_framework= world;
+}
tests/pool.h \
tests/print.h \
tests/replication.h \
+ tests/server_add.h \
tests/string.h \
tests/virtual_buckets.h
tests/pool.cc \
tests/print.cc \
tests/replication.cc \
+ tests/server_add.cc \
tests/virtual_buckets.cc
tests_testapp_SOURCES+= clients/generator.cc clients/execute.cc
tests_testapp_DEPENDENCIES= \
check_PROGRAMS+= tests/testplus
noinst_PROGRAMS+= tests/testplus
+tests_failure_SOURCES= tests/failure.cc
+tests_failure_CXXFLAGS = $(AM_CXXFLAGS)
+tests_failure_DEPENDENCIES= $(TESTS_LDADDS)
+tests_failure_LDADD= $(tests_failure_DEPENDENCIES)
+check_PROGRAMS+= tests/failure
+noinst_PROGRAMS+= tests/failure
+
tests_atomsmasher_SOURCES= \
tests/atomsmasher.cc \
tests/debug.cc \
gdb-cycle: tests/cycle
@$(DEBUG_COMMAND) tests/cycle
+gdb-failure: tests/failure
+ @$(DEBUG_COMMAND) tests/failure
+
valgrind-cycle: tests/cycle
$(VALGRIND_COMMAND) tests/cycle
valgrind-mem: tests/testapp
@$(VALGRIND_COMMAND) tests/testapp
+valgrind-failure: tests/failure
+ @$(VALGRIND_COMMAND) tests/failure
+
valgrind-atom: tests/atomsmasher
$(VALGRIND_COMMAND) tests/atomsmasher
valgrind-plus: tests/testplus
@$(VALGRIND_COMMAND) tests/testplus
+valgrind-sasl: tests/sasl
+ @$(VALGRIND_COMMAND) tests/sasl
+
valgrind-hash: tests/testhashkit
@$(VALGRIND_COMMAND) tests/testhashkit
valgrind-hashplus: tests/hash_plus
@$(VALGRIND_COMMAND) tests/hash_plus
-.PHONY += valgrind
-valgrind: valgrind-cycle valgrind-mem valgrind-udp valgrind-plus valgrind-hash valgrind-hashplus
-
helgrind-cycle: tests/cycle
@$(HELGRIND_COMMAND) tests/cycle
{ }
};
-#define SERVERS_TO_CREATE 5
-
static void *world_create(server_startup_st& servers, test_return_t& error)
{
- if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+ if (HAVE_MEMCACHED_BINARY == 0)
+ {
+ error= TEST_FATAL;
+ return NULL;
+ }
+
+ if (servers.sasl() and (LIBMEMCACHED_WITH_SASL_SUPPORT == 0 or MEMCACHED_SASL_BINARY == 0))
{
error= TEST_SKIPPED;
return NULL;
}
- in_port_t max_port;
- for (uint32_t x= 0; x < SERVERS_TO_CREATE; x++)
+ // Assume we are running under valgrind, and bail
+ if (servers.sasl() and getenv("TESTS_ENVIRONMENT"))
+ {
+ error= TEST_SKIPPED;
+ return NULL;
+ }
+
+
+ in_port_t max_port= TEST_PORT_BASE;
+ for (uint32_t x= 0; x < servers.count(); x++)
{
in_port_t port;
{
if (not server_startup(servers, "memcached-sasl", port, 1, argv))
{
- error= TEST_FAILURE;
+ error= TEST_FATAL;
return NULL;
}
}
{
if (not server_startup(servers, "memcached", port, 1, argv))
{
- error= TEST_FAILURE;
+ error= TEST_FATAL;
return NULL;
}
}
const char *argv[1]= { "memcached" };
if (not servers.start_socket_server("memcached-sasl", max_port +1, 1, argv))
{
- error= TEST_FAILURE;
+ error= TEST_FATAL;
return NULL;
}
}
const char *argv[1]= { "memcached" };
if (not servers.start_socket_server("memcached", max_port +1, 1, argv))
{
- error= TEST_FAILURE;
+ error= TEST_FATAL;
return NULL;
}
}
#define SMALL_STRING_LEN 1024
#include <libtest/test.hpp>
+
+#include "tests/basic.h"
+#include "tests/debug.h"
#include "tests/deprecated.h"
-#include "tests/parser.h"
+#include "tests/error_conditions.h"
#include "tests/ketama.h"
-#include "tests/pool.h"
#include "tests/namespace.h"
-#include "tests/replication.h"
-#include "tests/debug.h"
-#include "tests/basic.h"
-#include "tests/error_conditions.h"
+#include "tests/parser.h"
+#include "tests/pool.h"
#include "tests/print.h"
+#include "tests/replication.h"
+#include "tests/server_add.h"
#include "tests/virtual_buckets.h"
using namespace libtest;
return TEST_SUCCESS;
}
-static test_return_t error_test(memcached_st *memc)
+static test_return_t memcached_return_t_TEST(memcached_st *memc)
{
uint32_t values[] = { 851992627U, 2337886783U, 4109241422U, 4001849190U,
982370485U, 1263635348U, 4242906218U, 3829656100U,
54481931U, 4186304426U, 1741088401U, 2979625118U,
4159057246U, 3425930182U, 2593724503U, 1868899624U,
1769812374U, 2302537950U, 1110330676U, 3365377466U,
- 1336171666U, 3021258493U, 2334992265U, 3365377466U };
+ 1336171666U, 3021258493U, 2334992265U, 3861994737U,
+ 3365377466U };
// You have updated the memcache_error messages but not updated docs/tests.
for (int rc= int(MEMCACHED_SUCCESS); rc < int(MEMCACHED_MAXIMUM_RETURN); ++rc)
MEMCACHED_HASH_JENKINS);
if (values[rc] != hash_val)
{
- fprintf(stderr, "\n\nYou have updated memcached_return_t without updating the error_test\n");
+ fprintf(stderr, "\n\nYou have updated memcached_return_t without updating the memcached_return_t_TEST\n");
fprintf(stderr, "%u, %s, (%u)\n\n", (uint32_t)rc, memcached_strerror(memc, memcached_return_t(rc)), hash_val);
}
test_compare(values[rc], hash_val);
}
- test_compare(47, int(MEMCACHED_MAXIMUM_RETURN));
+ test_compare(48, int(MEMCACHED_MAXIMUM_RETURN));
return TEST_SUCCESS;
}
{
memcached_return_t rc;
const char *key= "foo bad";
- char *string;
- size_t string_length;
uint32_t flags;
memcached_st *memc_clone;
- unsigned int set= 1;
size_t max_keylen= 0xffff;
// Just skip if we are in binary mode.
query_id= memcached_query_id(memc_clone);
test_compare(MEMCACHED_SUCCESS,
- memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set));
+ memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, true));
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 (not memcached_behavior_get(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL))
{
query_id= memcached_query_id(memc_clone);
- string= memcached_get(memc_clone, key, strlen(key),
- &string_length, &flags, &rc);
- test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
- test_zero(string_length);
- test_false(string);
+ {
+ size_t string_length;
+ char *string= memcached_get(memc_clone, key, strlen(key),
+ &string_length, &flags, &rc);
+ test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
+ test_zero(string_length);
+ test_false(string);
+ }
- set= 0;
query_id= memcached_query_id(memc_clone);
test_compare(MEMCACHED_SUCCESS,
- memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set));
+ memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, false));
test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
- string= memcached_get(memc_clone, key, strlen(key),
- &string_length, &flags, &rc);
- test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
- test_zero(string_length);
- test_false(string);
+ {
+ size_t string_length;
+ char *string= memcached_get(memc_clone, key, strlen(key),
+ &string_length, &flags, &rc);
+ test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
+ test_zero(string_length);
+ test_false(string);
+ }
/* Test multi key for bad keys */
const char *keys[] = { "GoodKey", "Bad Key", "NotMine" };
size_t key_lengths[] = { 7, 7, 7 };
- set= 1;
query_id= memcached_query_id(memc_clone);
test_compare(MEMCACHED_SUCCESS,
- memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set));
+ memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, true));
test_compare(query_id, memcached_query_id(memc_clone));
query_id= memcached_query_id(memc_clone);
test_compare(MEMCACHED_SUCCESS,
memcached_callback_set(memc_clone, MEMCACHED_CALLBACK_NAMESPACE, NULL));
- char *longkey= (char *)malloc(max_keylen + 1);
- if (longkey)
+ std::vector <char> longkey;
+ longkey.insert(longkey.end(), max_keylen +1, 'a');
+ if (longkey.size())
{
- memset(longkey, 'a', max_keylen + 1);
- string= memcached_get(memc_clone, longkey, max_keylen,
- &string_length, &flags, &rc);
+ size_t string_length;
+ char *string= memcached_get(memc_clone, &longkey[0], max_keylen,
+ &string_length, &flags, &rc);
test_compare(MEMCACHED_NOTFOUND, rc);
test_zero(string_length);
test_false(string);
- string= memcached_get(memc_clone, longkey, max_keylen + 1,
+ string= memcached_get(memc_clone, &longkey[0], max_keylen +1,
&string_length, &flags, &rc);
test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
test_zero(string_length);
test_false(string);
-
- free(longkey);
}
}
/* Make sure zero length keys are marked as bad */
- set= 1;
- test_compare(MEMCACHED_SUCCESS,
- memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set));
- string= memcached_get(memc_clone, key, 0,
- &string_length, &flags, &rc);
- test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
- test_zero(string_length);
- test_false(string);
+ {
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, true));
+ size_t string_length;
+ char *string= memcached_get(memc_clone, key, 0,
+ &string_length, &flags, &rc);
+ test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
+ test_zero(string_length);
+ test_false(string);
+ }
memcached_free(memc_clone);
memcached_return_t 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_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
test_compare(query_id +1, memcached_query_id(memc));
}
// this should indicate end
string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
- test_true(rc == MEMCACHED_END);
+ test_compare(MEMCACHED_END, rc);
return TEST_SUCCESS;
}
return TEST_SUCCESS;
}
+static test_return_t binary_increment_with_prefix_test(memcached_st *orig_memc)
+{
+ memcached_st *memc= memcached_clone(NULL, orig_memc);
+
+ test_skip(TEST_SUCCESS, pre_binary(memc));
+
+ test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)"namespace:"));
+
+ memcached_return_t rc;
+ rc= memcached_set(memc,
+ test_literal_param("number"),
+ test_literal_param("0"),
+ (time_t)0, (uint32_t)0);
+ test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+
+ uint64_t new_number;
+ test_compare(MEMCACHED_SUCCESS, memcached_increment(memc,
+ test_literal_param("number"),
+ 1, &new_number));
+ test_compare(uint64_t(1), new_number);
+
+ test_compare(MEMCACHED_SUCCESS, memcached_increment(memc,
+ test_literal_param("number"),
+ 1, &new_number));
+ test_compare(uint64_t(2), new_number);
+ memcached_free(memc);
+
+ return TEST_SUCCESS;
+}
static test_return_t quit_test(memcached_st *memc)
{
rc= memcached_set(memc, key, strlen(key),
value, strlen(value),
(time_t)10, (uint32_t)3);
- test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
+ test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
memcached_quit(memc);
rc= memcached_set(memc, key, strlen(key),
rc= memcached_set(memc, keys[x], key_length[x],
keys[x], key_length[x],
(time_t)50, (uint32_t)9);
- test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+ test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
}
test_compare(MEMCACHED_SUCCESS,
rc= memcached_set(memc, keys[x], key_length[x],
keys[x], key_length[x],
(time_t)50, (uint32_t)9);
- test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+ test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
}
test_compare(MEMCACHED_SUCCESS,
rc= memcached_set(memc, keys[x], key_length[x],
keys[x], key_length[x],
(time_t)50, (uint32_t)9);
- test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+ test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
}
test_compare(MEMCACHED_SUCCESS,
memcached_mget(memc, keys, key_length, 3));
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_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
test_compare(query_id +1, memcached_query_id(memc));
}
/* We are testing with aggressive timeout to get failures */
static test_return_t user_supplied_bug10(memcached_st *memc)
{
- const char *key= "foo";
size_t value_length= 512;
- size_t key_len= 3;
unsigned int set= 1;
memcached_st *mclone= memcached_clone(NULL, memc);
memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
- int32_t timeout= 0;
- memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, (uint64_t)timeout);
+ memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, uint64_t(0));
char *value= (char*)malloc(value_length * sizeof(char));
for (unsigned int x= 1; x <= 100000; ++x)
{
- memcached_return_t rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
+ memcached_return_t rc= memcached_set(mclone,
+ test_literal_param("foo"),
+ value, value_length, 0, 0);
- test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_BUFFERED or rc == MEMCACHED_TIMEOUT or rc == MEMCACHED_CONNECTION_FAILURE,
+ test_true_got((rc == MEMCACHED_SUCCESS or rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_BUFFERED or rc == MEMCACHED_TIMEOUT or rc == MEMCACHED_CONNECTION_FAILURE
+ or rc == MEMCACHED_SERVER_TEMPORARILY_DISABLED),
memcached_strerror(NULL, rc));
if (rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_TIMEOUT)
*/
static test_return_t user_supplied_bug14(memcached_st *memc)
{
- size_t setter= 1;
- memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
- memcached_return_t rc;
- const char *key= "foo";
- char *value;
- size_t value_length= 18000;
- char *string;
- size_t string_length;
- uint32_t flags;
- unsigned int x;
- size_t current_length;
-
- value = (char*)malloc(value_length);
- test_true(value);
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
- for (x= 0; x < value_length; x++)
- value[x] = (char) (x % 127);
+ std::vector<char> value;
+ for (size_t x= 0; x < 18000; x++)
+ {
+ value.push_back((char) (x % 127));
+ }
- for (current_length= 0; current_length < value_length; current_length++)
+ for (size_t current_length= 0; current_length < value.size(); current_length++)
{
- rc= memcached_set(memc, key, strlen(key),
- value, current_length,
- (time_t)0, (uint32_t)0);
- test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+ memcached_return_t rc= memcached_set(memc, test_literal_param("foo"),
+ &value[0], current_length,
+ (time_t)0, (uint32_t)0);
+ test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
- string= memcached_get(memc, key, strlen(key),
- &string_length, &flags, &rc);
+ size_t string_length;
+ uint32_t flags;
+ char *string= memcached_get(memc, test_literal_param("foo"),
+ &string_length, &flags, &rc);
test_compare(MEMCACHED_SUCCESS, rc);
- test_true(string_length == current_length);
- test_memcmp(string, value, string_length);
+ test_compare(string_length, current_length);
+ test_memcmp(string, &value[0], string_length);
free(string);
}
- free(value);
-
return TEST_SUCCESS;
}
*/
static test_return_t user_supplied_bug15(memcached_st *memc)
{
- uint32_t x;
- memcached_return_t rc;
- const char *key= "mykey";
- size_t length;
- uint32_t flags;
-
- for (x= 0; x < 2; x++)
+ for (uint32_t x= 0; x < 2; x++)
{
- rc= memcached_set(memc, key, strlen(key),
- NULL, 0,
- (time_t)0, (uint32_t)0);
+ memcached_return_t rc= memcached_set(memc, test_literal_param("mykey"),
+ NULL, 0,
+ (time_t)0, (uint32_t)0);
test_compare(MEMCACHED_SUCCESS, rc);
- char *value= memcached_get(memc, key, strlen(key),
+ size_t length;
+ uint32_t flags;
+ char *value= memcached_get(memc, test_literal_param("mykey"),
&length, &flags, &rc);
test_compare(MEMCACHED_SUCCESS, rc);
test_false(value);
- test_false(length);
- test_false(flags);
+ test_zero(length);
+ test_zero(flags);
- value= memcached_get(memc, key, strlen(key),
+ value= memcached_get(memc, test_literal_param("mykey"),
&length, &flags, &rc);
test_compare(MEMCACHED_SUCCESS, rc);
test_true(value == NULL);
- test_true(length == 0);
- test_true(flags == 0);
+ test_zero(length);
+ test_zero(flags);
}
return TEST_SUCCESS;
/* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
static test_return_t user_supplied_bug16(memcached_st *memc)
{
- memcached_return_t rc;
- const char *key= "mykey";
- char *value;
- size_t length;
- uint32_t flags;
-
- rc= memcached_set(memc, key, strlen(key),
- NULL, 0,
- (time_t)0, UINT32_MAX);
+ memcached_return_t rc= memcached_set(memc, test_literal_param("mykey"),
+ NULL, 0,
+ (time_t)0, UINT32_MAX);
test_compare(MEMCACHED_SUCCESS, rc);
- value= memcached_get(memc, key, strlen(key),
+ size_t length;
+ uint32_t flags;
+ char *value= memcached_get(memc, test_literal_param("mykey"),
&length, &flags, &rc);
test_compare(MEMCACHED_SUCCESS, rc);
test_true(value == NULL);
- test_true(length == 0);
- test_true(flags == UINT32_MAX);
+ test_zero(length);
+ test_compare(flags, UINT32_MAX);
return TEST_SUCCESS;
}
/* Check the validity of chinese key*/
static test_return_t user_supplied_bug17(memcached_st *memc)
{
- memcached_return_t rc;
const char *key= "豆瓣";
const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
- char *value2;
- size_t length;
- uint32_t flags;
-
- rc= memcached_set(memc, key, strlen(key),
- value, strlen(value),
- (time_t)0, 0);
+ memcached_return_t rc= memcached_set(memc, key, strlen(key),
+ value, strlen(value),
+ (time_t)0, 0);
test_compare(MEMCACHED_SUCCESS, rc);
- value2= memcached_get(memc, key, strlen(key),
- &length, &flags, &rc);
+ size_t length;
+ uint32_t flags;
+ char *value2= memcached_get(memc, key, strlen(key),
+ &length, &flags, &rc);
test_true(length==strlen(value));
test_compare(MEMCACHED_SUCCESS, rc);
/* CAS test from Andei */
static test_return_t user_supplied_bug20(memcached_st *memc)
{
- memcached_return_t status;
- memcached_result_st *result, result_obj;
- const char *key = "abc";
- size_t key_len = strlen("abc");
- const char *value = "foobar";
- size_t value_len = strlen(value);
+ const char *key= "abc";
+ size_t key_len= strlen("abc");
- memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
+ test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
- status = memcached_set(memc, key, key_len, value, value_len, (time_t)0, (uint32_t)0);
- test_true(status == MEMCACHED_SUCCESS);
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_set(memc,
+ test_literal_param("abc"),
+ test_literal_param("foobar"),
+ (time_t)0, (uint32_t)0));
- status = memcached_mget(memc, &key, &key_len, 1);
- test_true(status == MEMCACHED_SUCCESS);
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_mget(memc, &key, &key_len, 1));
- result= memcached_result_create(memc, &result_obj);
+ memcached_result_st result_obj;
+ memcached_result_st *result= memcached_result_create(memc, &result_obj);
test_true(result);
memcached_result_create(memc, &result_obj);
+ memcached_return_t status;
result= memcached_fetch_result(memc, &result_obj, &status);
test_true(result);
- test_true(status == MEMCACHED_SUCCESS);
+ test_compare(MEMCACHED_SUCCESS, status);
memcached_result_free(result);
test_true(memc_clone);
/* only binproto uses getq for mget */
- test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
+ test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
/* empty the cache to ensure misses (hence non-responses) */
test_compare(MEMCACHED_SUCCESS, memcached_flush(memc_clone, 0));
test_rc= pre_binary(memc);
if (test_rc != TEST_SUCCESS)
+ {
return test_rc;
+ }
/* should work as of r580 */
test_compare(TEST_SUCCESS,
return TEST_SUCCESS;
}
-static test_return_t output_ketama_weighted_keys(memcached_st *trash)
+static test_return_t output_ketama_weighted_keys(memcached_st *)
{
- (void) trash;
-
- memcached_return_t rc;
memcached_st *memc= memcached_create(NULL);
test_true(memc);
- rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
- test_compare(MEMCACHED_SUCCESS, rc);
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, true));
uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
- test_true(value == 1);
+ test_compare(value, uint64_t(1));
- rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
- test_compare(MEMCACHED_SUCCESS, rc);
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5));
value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
test_true(value == MEMCACHED_HASH_MD5);
static test_return_t result_static(memcached_st *memc)
{
memcached_result_st result;
- memcached_result_st *result_ptr;
-
- result_ptr= memcached_result_create(memc, &result);
- test_true(result.options.is_allocated == false);
- test_true(memcached_is_initialized(&result) == true);
+ memcached_result_st *result_ptr= memcached_result_create(memc, &result);
+ test_false(result.options.is_allocated);
+ test_true(memcached_is_initialized(&result));
test_true(result_ptr);
test_true(result_ptr == &result);
memcached_result_free(&result);
- test_true(result.options.is_allocated == false);
- test_true(memcached_is_initialized(&result) == false);
+ test_false(result.options.is_allocated);
+ test_false(memcached_is_initialized(&result));
return TEST_SUCCESS;
}
static test_return_t result_alloc(memcached_st *memc)
{
- memcached_result_st *result_ptr;
-
- result_ptr= memcached_result_create(memc, NULL);
+ memcached_result_st *result_ptr= memcached_result_create(memc, NULL);
test_true(result_ptr);
- test_true(result_ptr->options.is_allocated == true);
- test_true(memcached_is_initialized(result_ptr) == true);
+ test_true(result_ptr->options.is_allocated);
+ test_true(memcached_is_initialized(result_ptr));
memcached_result_free(result_ptr);
return TEST_SUCCESS;
return TEST_SUCCESS;
}
-static test_return_t generate_pairs(memcached_st *memc)
+static test_return_t generate_pairs(memcached_st *)
{
- (void)memc;
global_pairs= pairs_generate(GLOBAL_COUNT, 400);
global_count= GLOBAL_COUNT;
for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
{
/* This test was changes so that "make test" would work properlly */
-#ifdef DEBUG
- memcached_server_instance_st instance=
- memcached_server_instance_by_position(memc, host_index);
+ if (DEBUG)
+ {
+ memcached_server_instance_st instance=
+ memcached_server_instance_by_position(memc, host_index);
- printf("\nserver %u|%s|%u bytes: %llu\n", host_index, instance->hostname, instance->port, (unsigned long long)(stat_p + host_index)->bytes);
-#endif
+ printf("\nserver %u|%s|%u bytes: %llu\n", host_index, instance->hostname, instance->port, (unsigned long long)(stat_p + host_index)->bytes);
+ }
test_true((unsigned long long)(stat_p + host_index)->bytes);
}
}
static test_return_t generate_buffer_data(memcached_st *memc)
{
- size_t latch= 0;
-
- latch= 1;
- memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true);
generate_data(memc);
return TEST_SUCCESS;
unsigned int keys_returned;
test_compare(TEST_SUCCESS, fetch_all_results(memc, keys_returned, MEMCACHED_SUCCESS));
test_true(keys_returned > 0);
- test_compare_got(global_count, keys_returned, "Possible false, positive, memcached may have ejected key/value based on memory needs");
+ test_compare_warn_hint(global_count, keys_returned, "Possible false, positive, memcached may have ejected key/value based on memory needs");
}
return TEST_SUCCESS;
static test_return_t delete_buffer_generate(memcached_st *memc)
{
- uint64_t latch= 1;
- memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true);
for (size_t x= 0; x < global_count; x++)
{
test_compare(MEMCACHED_SUCCESS, rc);
uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
- test_true(value == 1);
+ test_compare(value, uint64_t(1));
return TEST_SUCCESS;
}
test_compare(MEMCACHED_SUCCESS, rc);
uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
- test_true(value == 1);
+ test_compare(value, uint64_t(1));
- rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
- test_compare(MEMCACHED_SUCCESS, rc);
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5));
value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
- test_true(value == MEMCACHED_HASH_MD5);
+ test_compare(MEMCACHED_HASH_MD5, memcached_hash_t(value));
return TEST_SUCCESS;
}
static test_return_t set_memory_alloc(memcached_st *memc)
{
- test_compare(MEMCACHED_FAILURE,
+ test_compare(MEMCACHED_INVALID_ARGUMENTS,
memcached_set_memory_allocators(memc, NULL, my_free,
my_realloc, my_calloc, NULL));
memcached_hash_t hash;
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
+ {
return rc;
+ }
value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
static test_return_t noreply_test(memcached_st *memc)
{
- memcached_return_t ret;
- ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
- test_true(ret == MEMCACHED_SUCCESS);
- ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
- test_true(ret == MEMCACHED_SUCCESS);
- ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
- test_true(ret == MEMCACHED_SUCCESS);
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1));
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1));
test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
+ memcached_return_t ret;
for (int count=0; count < 5; ++count)
{
for (size_t x= 0; x < 100; ++x)
test_true(count);
break;
}
- test_true(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
+ test_true_got(ret == MEMCACHED_SUCCESS or ret == MEMCACHED_BUFFERED, memcached_strerror(NULL, ret));
}
/*
}
test_true(no_msg == 0);
- test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
+ test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
/*
** Now validate that all items was set properly!
uint32_t flags;
char* value=memcached_get(memc, key, strlen(key),
&length, &flags, &ret);
- test_true(ret == MEMCACHED_SUCCESS && value != NULL);
+ test_true_got(ret == MEMCACHED_SUCCESS && value != NULL, memcached_strerror(NULL, ret));
switch (count)
{
case 0: /* FALLTHROUGH */
uint32_t flags;
memcached_result_st results_obj;
memcached_result_st *results;
- ret= memcached_mget(memc, keys, lengths, 1);
- test_true(ret == MEMCACHED_SUCCESS);
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_mget(memc, keys, lengths, 1));
results= memcached_result_create(memc, &results_obj);
test_true(results);
results= memcached_fetch_result(memc, &results_obj, &ret);
test_true(results);
- test_true(ret == MEMCACHED_SUCCESS);
+ test_compare(MEMCACHED_SUCCESS, ret);
uint64_t cas= memcached_result_cas(results);
memcached_result_free(&results_obj);
- ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
- test_true(ret == MEMCACHED_SUCCESS);
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
/*
* The item will have a new cas value, so try to set it again with the old
* value. This should fail!
*/
- ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
- test_true(ret == MEMCACHED_SUCCESS);
+ test_compare(MEMCACHED_SUCCESS,
+ memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
test_true(ret == MEMCACHED_SUCCESS && value != NULL);
test_true(if_successful == true);
if (instance->micro_version > 0)
+ {
if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1));
+ }
else if (instance->minor_version > 0)
+ {
if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
+ }
else if (instance->major_version > 0)
+ {
if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version);
+ }
test_true(if_successful == true);
if (instance->micro_version > 0)
+ {
if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1));
+ }
else if (instance->minor_version > 0)
+ {
if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
+ }
else if (instance->major_version > 0)
+ {
if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version);
+ }
test_true(if_successful == false);
size_t len;
uint32_t flags;
memcached_return rc;
- char *value;
// See if memcached is reachable.
- value= memcached_get(memc, key, strlen(key), &len, &flags, &rc);
+ char *value= memcached_get(memc, key, strlen(key), &len, &flags, &rc);
test_false(value);
test_zero(len);
{
const char *msg= memcached_strerror(memc, memcached_return_t(x));
memcached_return_t ret= memcached_set(memc, msg, strlen(msg), NULL, 0, (time_t)0, (uint32_t)0);
- test_compare_got(MEMCACHED_CONNECTION_FAILURE, ret, memcached_last_error_message(memc));
+ test_true_got((ret == MEMCACHED_CONNECTION_FAILURE or ret == MEMCACHED_SERVER_TEMPORARILY_DISABLED), memcached_last_error_message(memc));
memcached_server_instance_st disconnected_server= memcached_server_get_last_disconnect(memc);
test_true(disconnected_server);
return TEST_SUCCESS;
}
-static test_return_t test_server_failure(memcached_st *memc)
-{
- if (memcached_server_count(memc) < 2)
- return TEST_SKIPPED;
-
- memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
-
- memcached_st *local_memc= memcached_create(NULL);
-
- memcached_server_add(local_memc, memcached_server_name(instance), memcached_server_port(instance));
- memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 2);
-
- uint32_t server_count= memcached_server_count(local_memc);
- test_compare(1U, server_count);
-
- // Disable the server
- instance= memcached_server_instance_by_position(local_memc, 0);
- ((memcached_server_write_instance_st)instance)->server_failure_counter= 2;
-
- memcached_return_t rc;
- test_compare_got(MEMCACHED_SERVER_MARKED_DEAD,
- rc= memcached_set(local_memc, "foo", strlen("foo"), NULL, 0, (time_t)0, (uint32_t)0),
- memcached_last_error_message(local_memc));
-
- ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
- test_compare(MEMCACHED_SUCCESS,
- memcached_set(local_memc, "foo", strlen("foo"), NULL, 0, (time_t)0, (uint32_t)0));
-#if 0
- memcached_last_error_message(local_memc));
-#endif
-
-
- memcached_free(local_memc);
-
- return TEST_SUCCESS;
-}
-
-static test_return_t test_cull_servers(memcached_st *memc)
-{
- uint32_t count= memcached_server_count(memc);
-
- if (count < 2)
- {
- return TEST_SKIPPED;
- }
-
- // Do not do this in your code, it is not supported.
- memc->servers[1].options.is_dead= true;
- memc->state.is_time_for_rebuild= true;
-
- uint32_t new_count= memcached_server_count(memc);
- test_compare(count, new_count);
-
-#if 0
- test_true(count == new_count + 1 );
-#endif
-
- return TEST_SUCCESS;
-}
-
static memcached_return_t stat_printer(memcached_server_instance_st server,
const char *key, size_t key_length,
{"connection_test", false, (test_callback_fn*)connection_test},
{"callback_test", false, (test_callback_fn*)callback_test},
{"userdata_test", false, (test_callback_fn*)userdata_test},
- {"error", false, (test_callback_fn*)error_test },
{"set", false, (test_callback_fn*)set_test },
{"set2", false, (test_callback_fn*)set_test2 },
{"set3", false, (test_callback_fn*)set_test3 },
{"increment_with_initial_by_key", true, (test_callback_fn*)increment_with_initial_by_key_test },
{"decrement_by_key", false, (test_callback_fn*)decrement_by_key_test },
{"decrement_with_initial_by_key", true, (test_callback_fn*)decrement_with_initial_by_key_test },
+ {"binary_increment_with_prefix", 1, (test_callback_fn*)binary_increment_with_prefix_test },
{"quit", false, (test_callback_fn*)quit_test },
{"mget", true, (test_callback_fn*)mget_test },
{"mget_result", true, (test_callback_fn*)mget_result_test },
{"memcached_pool_test", true, (test_callback_fn*)memcached_pool_test },
{"test_get_last_disconnect", true, (test_callback_fn*)test_get_last_disconnect},
{"verbosity", true, (test_callback_fn*)test_verbosity},
- {"test_server_failure", true, (test_callback_fn*)test_server_failure},
- {"cull_servers", true, (test_callback_fn*)test_cull_servers},
{"memcached_stat_execute", true, (test_callback_fn*)memcached_stat_execute_test},
{0, 0, 0}
};
{"reset heap", true, (test_callback_fn*)basic_reset_heap_test},
{"reset stack clone", true, (test_callback_fn*)basic_reset_stack_clone_test},
{"reset heap clone", true, (test_callback_fn*)basic_reset_heap_clone_test},
+ {"memcached_return_t", false, (test_callback_fn*)memcached_return_t_TEST },
{0, 0, 0}
};
{0, 0, (test_callback_fn*)0}
};
+test_st memcached_server_add_tests[] ={
+ {"memcached_server_add(\"\")", false, (test_callback_fn*)memcached_server_add_empty_test },
+ {"memcached_server_add(NULL)", false, (test_callback_fn*)memcached_server_add_null_test },
+ {0, 0, (test_callback_fn*)0}
+};
+
test_st namespace_tests[] ={
{"basic tests", true, (test_callback_fn*)selection_of_namespace_tests },
{"increment", true, (test_callback_fn*)memcached_increment_namespace },
{"basic", 0, 0, basic_tests},
{"hsieh_availability", 0, 0, hsieh_availability},
{"murmur_availability", 0, 0, murmur_availability},
+ {"memcached_server_add", 0, 0, memcached_server_add_tests},
{"block", 0, 0, tests},
{"binary", (test_callback_fn*)pre_binary, 0, tests},
{"nonblock", (test_callback_fn*)pre_nonblock, 0, tests},
{"async", (test_callback_fn*)pre_nonblock, 0, async_tests},
{"async(BINARY)", (test_callback_fn*)pre_nonblock_binary, 0, async_tests},
{"Cal Haldenbrand's tests", 0, 0, haldenbrand_tests},
- {"user", 0, 0, user_tests},
+ {"user written tests", 0, 0, user_tests},
{"generate", 0, 0, generate_tests},
{"generate_hsieh", (test_callback_fn*)pre_hsieh, 0, generate_tests},
{"generate_ketama", (test_callback_fn*)pre_behavior_ketama, 0, generate_tests},
using namespace libtest;
-#include <libmemcached/common.h>
+#include <libmemcached/memcached.h>
+#include <libmemcached/server_instance.h>
+#include <libmemcached/io.h>
#include <assert.h>
#include <stdio.h>
#include <libtest/server.h>
-#define SERVERS_TO_CREATE 5
-
#ifndef __INTEL_COMPILER
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
{0, 0, 0, 0}
};
-#define SERVERS_TO_CREATE 5
-
#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT +10
#include "libmemcached_world.h"
snprintf(buffer, sizeof(buffer), "-p %d", int(default_port()));
const char *args[]= { buffer, "--help", 0 };
- test_success(exec_cmdline(executable, args));
+ test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
snprintf(buffer, sizeof(buffer), "-p %d", int(default_port()));
const char *args[]= { buffer, " -a ", 0 };
- test_success(exec_cmdline(executable, args));
+ test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
snprintf(buffer, sizeof(buffer), "-p %d", int(default_port()));
const char *args[]= { buffer, " -b ", 0 };
- test_success(exec_cmdline(executable, args));
+ test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
const char *args[]= { "--help", 0 };
- test_success(exec_cmdline(executable, args));
+ test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
const char *args[]= { buffer, 0 };
- test_success(exec_cmdline(executable, args));
+ test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
const char *args[]= { buffer, "--concurrency=10", 0 };
- test_success(exec_cmdline(executable, args));
+ test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", 0 };
- test_success(exec_cmdline(executable, args));
+ test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", 0 };
- test_success(exec_cmdline(executable, args));
+ test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", "--test=get", 0 };
- test_success(exec_cmdline(executable, args));
+ test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", "--test=set", 0 };
- test_success(exec_cmdline(executable, args));
+ test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", "--test=set", "--non-blocking", 0 };
- test_success(exec_cmdline(executable, args));
+ test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
#pragma once
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t memcached_increment_namespace(memcached_st *memc);
#include <cerrno>
#include <cassert>
-#define BUILDING_LIBMEMCACHED
-// !NEVER use common.h, always use memcached.h in your own apps
-#include <libmemcached/common.h>
+#include <libmemcached/memcached.h>
#include <libmemcached/util.h>
#include <tests/parser.h>
char *value= memcached_get(memc, test_literal_param("test"), &value_len, NULL, &rc);
test_false(value);
test_zero(value_len);
+#ifdef __APPLE__
+ test_compare_got(MEMCACHED_CONNECTION_FAILURE, rc, memcached_last_error_message(memc));
+#else
test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_last_error_message(memc));
+#endif
memcached_free(memc);
}
extern "C" {
#endif
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t server_test(memcached_st *memc);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t servers_bad_test(memcached_st *memc);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t behavior_parser_test(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t parser_number_options_test(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t parser_distribution_test(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t parser_hash_test(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t parser_boolean_options_test(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t parser_key_prefix_test(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t libmemcached_check_configuration_test(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t memcached_create_with_options_test(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t memcached_create_with_options_with_filename(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t libmemcached_check_configuration_with_filename_test(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t random_statement_build_test(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t test_include_keyword(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t test_end_keyword(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t test_reset_keyword(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t test_error_keyword(memcached_st*);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t server_with_weight_test(memcached_st *);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t test_hostname_port_weight(memcached_st *);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t regression_bug_71231153_connect(memcached_st *);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t regression_bug_71231153_poll(memcached_st *);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t test_parse_socket(memcached_st *);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t test_namespace_keyword(memcached_st*);
#ifdef __cplusplus
using namespace memcache;
using namespace libtest;
-extern "C" {
- test_return_t basic_test(memcached_st *memc);
- test_return_t increment_test(memcached_st *memc);
- test_return_t basic_master_key_test(memcached_st *memc);
- test_return_t mget_result_function(memcached_st *memc);
- test_return_t basic_behavior(memcached_st *memc);
- test_return_t mget_test(memcached_st *memc);
- memcached_return_t callback_counter(const memcached_st *,
- memcached_result_st *,
- void *context);
-}
-
static void populate_vector(vector<char> &vec, const string &str)
{
vec.reserve(str.length());
}
}
-test_return_t basic_test(memcached_st *memc)
+static test_return_t basic_test(memcached_st *memc)
{
Memcache foo(memc);
const string value_set("This is some data");
return TEST_SUCCESS;
}
-test_return_t increment_test(memcached_st *original)
+static test_return_t increment_test(memcached_st *original)
{
Memcache mcach(original);
const string key("blah");
return TEST_SUCCESS;
}
-test_return_t basic_master_key_test(memcached_st *original)
+static test_return_t basic_master_key_test(memcached_st *original)
{
Memcache foo(original);
const string value_set("Data for server A");
return TEST_SUCCESS;
}
-/* Count the results */
-memcached_return_t callback_counter(const memcached_st *,
- memcached_result_st *,
- void *context)
-{
- unsigned int *counter= static_cast<unsigned int *>(context);
-
- *counter= *counter +1;
-
- return MEMCACHED_SUCCESS;
-}
-
-test_return_t mget_test(memcached_st *original)
+static test_return_t mget_test(memcached_st *original)
{
Memcache memc(original);
memcached_return_t mc_rc;
return TEST_SUCCESS;
}
-test_return_t basic_behavior(memcached_st *original)
+static test_return_t basic_behavior(memcached_st *original)
{
Memcache memc(original);
uint64_t value= 1;
return TEST_SUCCESS;
}
+static test_return_t error_test(memcached_st *)
+{
+ Memcache memc("--server=localhost:0");
+ std::vector<char> value;
+
+ test_false(memc.set("key", value, time_t(0), uint32_t(0)));
+
+ test_true(memc.error());
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t error_std_string_test(memcached_st *)
+{
+ Memcache memc("--server=localhost:0");
+ std::vector<char> value;
+
+ test_false(memc.set("key", value, time_t(0), uint32_t(0)));
+
+ std::string error_message;
+ test_true(memc.error(error_message));
+ test_false(error_message.empty());
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t error_memcached_return_t_test(memcached_st *)
+{
+ Memcache memc("--server=localhost:0");
+ std::vector<char> value;
+
+ test_false(memc.set("key", value, time_t(0), uint32_t(0)));
+
+ memcached_return_t rc;
+ test_true(memc.error(rc));
+ test_compare(MEMCACHED_CONNECTION_FAILURE, rc);
+
+ return TEST_SUCCESS;
+}
+
+test_st error_tests[] ={
+ { "error()", false, reinterpret_cast<test_callback_fn*>(error_test) },
+ { "error(std::string&)", false, reinterpret_cast<test_callback_fn*>(error_std_string_test) },
+ { "error(memcached_return_t&)", false, reinterpret_cast<test_callback_fn*>(error_memcached_return_t_test) },
+ {0, 0, 0}
+};
+
test_st tests[] ={
- { "basic", 0,
+ { "basic", false,
reinterpret_cast<test_callback_fn*>(basic_test) },
- { "basic_master_key", 0,
+ { "basic_master_key", false,
reinterpret_cast<test_callback_fn*>(basic_master_key_test) },
- { "increment_test", 0,
+ { "increment_test", false,
reinterpret_cast<test_callback_fn*>(increment_test) },
- { "mget", 1,
+ { "mget", true,
reinterpret_cast<test_callback_fn*>(mget_test) },
- { "basic_behavior", 0,
+ { "basic_behavior", false,
reinterpret_cast<test_callback_fn*>(basic_behavior) },
{0, 0, 0}
};
collection_st collection[] ={
{"block", 0, 0, tests},
+ {"error()", 0, 0, error_tests},
{0, 0, 0, 0}
};
extern "C" {
#endif
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t memcached_pool_test(memcached_st *);
#ifdef __cplusplus
extern "C" {
#endif
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
memcached_return_t server_print_callback(const memcached_st *ptr,
const memcached_server_st *server,
void *context);
using namespace libtest;
-#include <libmemcached/common.h>
+#include <libmemcached/memcached.h>
+#include <libmemcached/server_instance.h>
#include <tests/replication.h>
#include <tests/debug.h>
memcached_flush_buffers(memc_replicated);
// Confirm keys with replication read
- test_compare(TEST_SUCCESS, confirm_keys_exist(memc_replicated, keys, test_array_length(keys), true));
- test_compare(TEST_SUCCESS, confirm_keys_exist(memc_not_replicate, keys, test_array_length(keys), true));
+ test_compare(TEST_SUCCESS, confirm_keys_exist(memc_replicated, keys, test_array_length(keys), true, true));
+ test_compare(TEST_SUCCESS, confirm_keys_exist(memc_not_replicate, keys, test_array_length(keys), true, true));
/* Delete the items from all of the servers except 1, we use the non replicated memc so that we know we deleted the keys */
for (size_t x= 0; x < test_array_length(keys); ++x)
extern "C" {
#endif
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t replication_set_test(memcached_st *memc);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t replication_get_test(memcached_st *memc);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t replication_mget_test(memcached_st *memc);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t replication_delete_test(memcached_st *memc);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t replication_randomize_mget_test(memcached_st *memc);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t replication_randomize_mget_fail_test(memcached_st *memc);
#ifdef __cplusplus
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached Client and Server
+ *
+ * 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 <config.h>
+#include <libtest/test.hpp>
+
+using namespace libtest;
+
+#include <libmemcached/memcached.h>
+
+#include <tests/server_add.h>
+
+test_return_t memcached_server_add_null_test(memcached_st*)
+{
+ memcached_st *memc= memcached_create(NULL);
+
+ test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, NULL, 0));
+
+ memcached_free(memc);
+
+ return TEST_SUCCESS;
+}
+
+test_return_t memcached_server_add_empty_test(memcached_st*)
+{
+ memcached_st *memc= memcached_create(NULL);
+
+ test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "", 0));
+
+ memcached_free(memc);
+
+ return TEST_SUCCESS;
+}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached Client and Server
+ *
+ * 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
+
+test_return_t memcached_server_add_null_test(memcached_st*);
+test_return_t memcached_server_add_empty_test(memcached_st*);
extern "C" {
#endif
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t string_static_null(void *);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t string_alloc_null(void *);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t string_alloc_with_size(void *);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t string_alloc_with_size_toobig(void *);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t string_alloc_append(void *);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t string_alloc_append_toobig(void *);
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t string_alloc_append_multiple(void *);
#ifdef __cplusplus
extern "C" {
#endif
-LIBTEST_INTERNAL_API
+LIBTEST_LOCAL
test_return_t virtual_back_map(memcached_st *);
#ifdef __cplusplus
noinst_HEADERS+= \
util/daemon.hpp \
util/instance.hpp \
+ util/logfile.hpp \
util/operation.hpp \
util/signal.hpp \
util/string.hpp \
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * DataDifferential Utility 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 "config.h"
+
+#include "util/logfile.hpp"
+
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <fcntl.h>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+namespace datadifferential {
+namespace util {
+
+Logfile::Logfile(const std::string &arg) :
+ _filename(arg)
+{
+ time_t tmp= time(NULL);
+ _log_file << "shutdown: " << ctime(&tmp) << std::endl;
+}
+
+Logfile::~Logfile()
+{
+ if (not _filename.empty())
+ {
+ _log_file.close();
+ if (access(_filename.c_str(), F_OK) == -1)
+ { }
+ else if (unlink(_filename.c_str()) == -1)
+ { }
+ }
+}
+
+bool Logfile::open()
+{
+ if (_filename.empty())
+ {
+ _log_file.open("/dev/stderr");
+ return true;
+ }
+
+ _log_file.open(_filename.c_str());
+ if (not _log_file.good())
+ {
+ return false;
+ }
+
+ time_t tmp= time(NULL);
+ _log_file << "startup: " << ctime(&tmp) << std::endl;
+
+ return true;
+}
+
+} /* namespace util */
+} /* namespace datadifferential */
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * DataDifferential Utility 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 <string>
+#include <fstream>
+
+namespace datadifferential {
+namespace util {
+
+class Logfile
+{
+public:
+ Logfile(const std::string &arg);
+
+ ~Logfile();
+
+ std::ofstream &log()
+ {
+ return _log_file;
+ }
+
+ bool open();
+
+private:
+ const std::string _filename;
+ std::ofstream _log_file;
+};
+
+} /* namespace util */
+} /* namespace datadifferential */