tests/testudp
tests/var/
unittests/unittests
+libtest/version.h
+clients/memping
+libtest/skiptest
+tests/sasl
+tests/c_sasl_test
README.win32 \
config/autorun.sh \
config/pandora-plugin \
- config/uncrustify.cfg \
- m4/ac_cxx_header_stdcxx_98.m4 \
- m4/acx_pthread.m4 \
- m4/gettext.m4 \
- m4/iconv.m4 \
- m4/pkg.m4 \
- m4/po.m4 \
- m4/progtest.m4
+ config/uncrustify.cfg
libmemcached_libmemcached_la_LDFLAGS=
# All paths should be given relative to the root
CLIENTS_LDADDS= \
- $(LIBM) \
clients/libutilities.la \
libmemcached/libmemcached.la
clients/memerror \
clients/memflush \
clients/memparse \
+ clients/memping \
clients/memrm \
clients/memslap \
clients/memstat
clients_memflush_SOURCES= clients/memflush.cc
clients_memflush_LDADD= $(CLIENTS_LDADDS)
+clients_memping_SOURCES= clients/memping.cc
+clients_memping_LDADD= $(CLIENTS_LDADDS) libmemcached/libmemcachedutil.la
+
clients_memerror_SOURCES= clients/memerror.cc
clients_memerror_LDADD= $(CLIENTS_LDADDS)
clients_memslap_SOURCES = clients/memslap.cc
clients_memslap_SOURCES+= clients/generator.cc clients/execute.cc
clients_memslap_CXXFLAGS = ${PTHREAD_CFLAGS}
-clients_memslap_LDADD = $(PTHREAD_LIBS) $(CLIENTS_LDADDS)
+clients_memslap_LDADD= $(CLIENTS_LDADDS)
+clients_memslap_LDADD+= $(PTHREAD_LIBS)
clients_memaslap_SOURCES= \
clients/memaslap.c \
#include "config.h"
+#include <iostream>
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL,
(uint64_t)opt_binary);
- if (!initialize_sasl(memc, opt_username, opt_passwd))
+ if (opt_username and LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+ {
+ memcached_free(memc);
+ std::cerr << "--username was supplied, but binary was not built with SASL support." << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if (opt_username and initialize_sasl(memc, opt_username, opt_passwd) == false)
{
memcached_free(memc);
return EXIT_FAILURE;
#include "config.h"
+#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
memcached_server_list_free(servers);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL,
(uint64_t)opt_binary);
- if (!initialize_sasl(memc, opt_username, opt_passwd))
+
+ if (opt_username and LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+ {
+ memcached_free(memc);
+ std::cerr << "--username was supplied, but binary was not built with SASL support." << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if (initialize_sasl(memc, opt_username, opt_passwd) == false)
{
+ std::cerr << "Failed to initialize SASL support." << std::endl;
memcached_free(memc);
return EXIT_FAILURE;
}
#include "config.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <unistd.h>
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <fcntl.h>
#include <getopt.h>
-#include <sys/types.h>
+#include <inttypes.h>
+#include <iostream>
#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 <unistd.h>
#include <libmemcached/memcached.h>
memcached_server_list_free(servers);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL,
(uint64_t)opt_binary);
- if (!initialize_sasl(memc, opt_username, opt_passwd))
+
+ if (opt_username and LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
{
+ memcached_free(memc);
+ std::cerr << "--username was supplied, but binary was not built with SASL support." << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if (opt_username and initialize_sasl(memc, opt_username, opt_passwd) == false)
+ {
+ std::cerr << "Failed to initialize SASL support." << std::endl;
+
memcached_free(memc);
return EXIT_FAILURE;
}
*/
#include "config.h"
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
+#include <cstdio>
+#include <cstring>
#include <getopt.h>
+#include <iostream>
+#include <unistd.h>
+
#include <libmemcached/memcached.h>
#include "client_options.h"
#include "utilities.h"
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL,
(uint64_t) opt_binary);
+ if (opt_username and LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+ {
+ memcached_free(memc);
+ std::cerr << "--username was supplied, but binary was not built with SASL support." << std::endl;
+ return EXIT_FAILURE;
+ }
+
+
if (!initialize_sasl(memc, opt_username, opt_passwd))
{
memcached_free(memc);
--- /dev/null
+/* LibMemcached
+ * Copyright (C) 2006-2009 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license. See
+ * the COPYING file in the parent directory for full text.
+ *
+ * Summary:
+ *
+ */
+#include "config.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <getopt.h>
+#include <libmemcached/memcached.h>
+#include <libmemcached/util.h>
+#include "client_options.h"
+#include "utilities.h"
+
+#include <iostream>
+
+static int opt_binary= 0;
+static int opt_verbose= 0;
+static time_t opt_expire= 0;
+static char *opt_servers= NULL;
+static char *opt_username;
+static char *opt_passwd;
+
+#define PROGRAM_NAME "memping"
+#define PROGRAM_DESCRIPTION "Ping a server to see if it is alive"
+
+/* Prototypes */
+void options_parse(int argc, char *argv[]);
+
+int main(int argc, char *argv[])
+{
+ options_parse(argc, argv);
+
+ if (opt_servers == NULL)
+ {
+ char *temp;
+
+ if ((temp= getenv("MEMCACHED_SERVERS")))
+ {
+ opt_servers= strdup(temp);
+ }
+ else
+ {
+ std::cerr << "No Servers provided" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ int exit_code= EXIT_SUCCESS;
+ memcached_server_st *servers= memcached_servers_parse(opt_servers);
+ {
+ for (uint32_t x= 0; x < memcached_server_list_count(servers); x++)
+ {
+ memcached_return_t instance_rc;
+ const char *hostname= servers[x].hostname;
+ in_port_t port= servers[x].port;
+
+ if (libmemcached_util_ping2(hostname, port, opt_username, opt_passwd, &instance_rc) == false)
+ {
+ std::cerr << "Failed to ping " << hostname << ":" << port << " " << memcached_strerror(NULL, instance_rc) << std::endl;
+ exit_code= EXIT_FAILURE;
+ }
+ }
+ }
+ memcached_server_list_free(servers);
+
+ free(opt_servers);
+
+ shutdown_sasl();
+
+ return exit_code;
+}
+
+
+void options_parse(int argc, char *argv[])
+{
+ memcached_programs_help_st help_options[]=
+ {
+ {0},
+ };
+
+ static struct option long_options[]=
+ {
+ {(OPTIONSTRING)"version", no_argument, NULL, OPT_VERSION},
+ {(OPTIONSTRING)"help", no_argument, NULL, OPT_HELP},
+ {(OPTIONSTRING)"verbose", no_argument, &opt_verbose, OPT_VERBOSE},
+ {(OPTIONSTRING)"debug", no_argument, &opt_verbose, OPT_DEBUG},
+ {(OPTIONSTRING)"servers", required_argument, NULL, OPT_SERVERS},
+ {(OPTIONSTRING)"expire", required_argument, NULL, OPT_EXPIRE},
+ {(OPTIONSTRING)"binary", no_argument, NULL, OPT_BINARY},
+ {(OPTIONSTRING)"username", required_argument, NULL, OPT_USERNAME},
+ {(OPTIONSTRING)"password", required_argument, NULL, OPT_PASSWD},
+ {0, 0, 0, 0},
+ };
+ int option_index= 0;
+ int option_rv;
+
+ while (1)
+ {
+ option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index);
+ if (option_rv == -1) break;
+ switch (option_rv)
+ {
+ case 0:
+ break;
+ case OPT_BINARY:
+ opt_binary = 1;
+ break;
+ case OPT_VERBOSE: /* --verbose or -v */
+ opt_verbose = OPT_VERBOSE;
+ break;
+ case OPT_DEBUG: /* --debug or -d */
+ opt_verbose = OPT_DEBUG;
+ break;
+ case OPT_VERSION: /* --version or -V */
+ version_command(PROGRAM_NAME);
+ break;
+ case OPT_HELP: /* --help or -h */
+ help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options);
+ break;
+ case OPT_SERVERS: /* --servers or -s */
+ opt_servers= strdup(optarg);
+ break;
+ case OPT_EXPIRE: /* --expire */
+ opt_expire= (time_t)strtoll(optarg, (char **)NULL, 10);
+ break;
+ case OPT_USERNAME:
+ opt_username= optarg;
+ break;
+ case OPT_PASSWD:
+ opt_passwd= optarg;
+ break;
+ case '?':
+ /* getopt_long already printed an error message. */
+ exit(1);
+ default:
+ abort();
+ }
+ }
+}
*/
#include "config.h"
-#include <stdio.h>
-#include <unistd.h>
+#include <cstdio>
+#include <cstring>
#include <getopt.h>
+#include <iostream>
+#include <unistd.h>
+
#include <libmemcached/memcached.h>
-#include <string.h>
#include "client_options.h"
#include "utilities.h"
options_parse(argc, argv);
initialize_sockets();
- if (!opt_servers)
+ if (opt_servers == 0)
{
char *temp;
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL,
(uint64_t) opt_binary);
- if (!initialize_sasl(memc, opt_username, opt_passwd))
+ if (opt_username and LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+ {
+ memcached_free(memc);
+ std::cerr << "--username was supplied, but binary was not built with SASL support." << std::endl;
+ return EXIT_FAILURE;
+ }
+
+
+ if (opt_username and initialize_sasl(memc, opt_username, opt_passwd) == false)
{
+ std::cerr << "Failed to initialize SASL support." << std::endl;
+
memcached_free(memc);
return EXIT_FAILURE;
}
}
}
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
+
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;
*result= username;
if (len)
+ {
*len= (username == NULL) ? 0 : (unsigned int)strlen(username);
+ }
return SASL_OK;
}
{ 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)
{
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
+ 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;
- (void)user;
- (void)password;
+ (void)memc;
#endif
+ }
return true;
}
void shutdown_sasl(void)
{
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
- if (username != NULL || passwd != NULL)
+ 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 */
-#ifdef WIN32
+#if defined(WIN32) && WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,0), &wsaData) != 0)
{
#!/bin/sh
-autoreconf -ivf
+autoreconf -ivf -Wall
HASHKIT_LIBRARY_VERSION=1:0:0
AC_SUBST(HASHKIT_LIBRARY_VERSION)
-AC_DEFINE([HAVE_LIBMEMCACHED], [ 1 ], [dummy rule for libtest])
-AC_SUBST(HAVE_LIBMEMCACHED, 1)
-AM_CONDITIONAL(HAVE_LIBMEMCACHED, true)
LT_INIT
+m4_include([m4/memcached.m4])
+m4_include([m4/memcached_sasl.m4])
+
+AM_CONDITIONAL(BUILDING_LIBMEMCACHED, true)
+AM_CONDITIONAL(HAVE_LIBMEMCACHED, false)
+AC_SUBST(_WITH_LIBMEMCACHED_SUPPORT, ["_WITH_LIBMEMCACHED_SUPPORT 1"])
+
+AM_CONDITIONAL(BUILDING_GEARMAN, false)
+AM_CONDITIONAL(HAVE_LIBGEARMAN, false)
+AC_SUBST(_WITH_LIBGEARMAN_SUPPORT, ["_WITH_LIBGEARMAN_SUPPORT 0"])
AC_SEARCH_LIBS(getopt_long, gnugetopt)
AC_SEARCH_LIBS(gethostbyname, nsl)
PANDORA_HAVE_LIBEVENT
-my_saved_libs="$LIBS"
-LIBS=
-PANDORA_REQUIRE_PTHREAD
-LIBS="$my_saved_libs"
+
+case "$target_os" in
+ *linux*)
+ AS_IF([test "x$GCC" = "xyes"],
+ [
+ LDFLAGS="$LDFLAGS -z relro -z now"
+ ])
+ ;;
+ esac
dnl Specialty checks
+ACX_PTHREAD
CONFIG_EXTRA
DETECT_BYTEORDER
ENABLE_UTILLIB
ENABLE_MURMUR_HASH
ENABLE_MEMASLAP
PROTOCOL_BINARY_TEST
-WITH_MEMCACHED
ENABLE_DEPRECATED
PANDORA_HAVE_LIBINNODB
-PANDORA_PRINT_CALLSTACK
PANDORA_HAVE_SASL
-WITH_LIBGEARMAN
AC_CHECK_FUNCS([alarm])
AC_CHECK_FUNCS([dup2])
AC_CHECK_HEADERS([netinet/in.h])
AC_CHECK_HEADERS([stddef.h])
AC_CHECK_HEADERS([sys/time.h])
+AC_CHECK_HEADERS([sasl/sasl.h])
AC_FUNC_ALLOCA
AC_FUNC_ERROR_AT_LINE
AC_FUNC_FORK
dnl The sasl functions should only be visible if we build with sasl support
AS_IF([test "x$ac_cv_sasl" = "xyes"],
- [LIBMEMCACHED_WITH_SASL_SUPPORT="#define LIBMEMCACHED_WITH_SASL_SUPPORT 1"])
+ [
+ [ LIBMEMCACHED_WITH_SASL_SUPPORT="#define LIBMEMCACHED_WITH_SASL_SUPPORT 1" ]
+ ],
+ [
+ [ LIBMEMCACHED_WITH_SASL_SUPPORT="#define LIBMEMCACHED_WITH_SASL_SUPPORT 0" ]
+ ]
+ )
AC_SUBST(LIBMEMCACHED_WITH_SASL_SUPPORT)
AC_CHECK_HEADERS([atomic.h])
support/libmemcached.pc
support/libmemcached.spec
support/libmemcached-fc.spec
+ libtest/version.h
])
AC_OUTPUT
case MEMCACHED_CONNECTION_UDP:
case MEMCACHED_CONNECTION_TCP:
rc= network_connect(ptr);
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
- if (ptr->fd != INVALID_SOCKET and ptr->root->sasl.callbacks)
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT)
{
- rc= memcached_sasl_authenticate_connection(ptr);
- if (memcached_failed(rc) and ptr->fd != INVALID_SOCKET)
+ if (ptr->fd != INVALID_SOCKET and ptr->root->sasl.callbacks)
{
- WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
- (void)closesocket(ptr->fd);
- ptr->fd= INVALID_SOCKET;
+ rc= memcached_sasl_authenticate_connection(ptr);
+ if (memcached_failed(rc) and ptr->fd != INVALID_SOCKET)
+ {
+ WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
+ (void)closesocket(ptr->fd);
+ ptr->fd= INVALID_SOCKET;
+ }
}
}
-#endif
break;
case MEMCACHED_CONNECTION_UNIX_SOCKET:
libmemcached_libmemcached_la_LIBADD= $(LIBM)
libmemcached_libmemcached_la_LDFLAGS+= ${AM_LDFLAGS} -version-info ${MEMCACHED_LIBRARY_VERSION}
-if HAVE_SASL
-libmemcached_libmemcached_la_LDFLAGS+= $(LTLIBSASL) $(LTLIBSASL2)
-libmemcached_libmemcached_la_SOURCES += libmemcached/sasl.c
-endif
+libmemcached_libmemcached_la_LIBADD+= $(LTLIBSASL) $(LTLIBSASL2)
+libmemcached_libmemcached_la_SOURCES += libmemcached/sasl.cc
if HAVE_DTRACE
BUILT_SOURCES+= libmemcached/dtrace_probes.h
memcached_error_free(*ptr);
- if (ptr->sasl.callbacks)
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT and ptr->sasl.callbacks)
{
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
memcached_destroy_sasl_auth_data(ptr);
-#endif
}
if (release_st)
new_clone->_namespace= memcached_array_clone(new_clone, source->_namespace);
new_clone->configure.filename= memcached_array_clone(new_clone, source->_namespace);
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
- if (source->sasl.callbacks)
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT and source->sasl.callbacks)
{
if (memcached_clone_sasl(new_clone, source) != MEMCACHED_SUCCESS)
{
return NULL;
}
}
-#endif
rc= run_distribution(new_clone);
libmemcached_libmemcachedprotocol_la_CFLAGS= \
${AM_CFLAGS} \
${NO_CONVERSION} \
- ${PTHREAD_CFLAGS} \
-DBUILDING_LIBMEMCACHED
+libmemcached_libmemcachedprotocol_la_CFLAGS+= ${PTHREAD_CFLAGS}
libmemcached_libmemcachedprotocol_la_CXXFLAGS= \
${AM_CXXFLAGS} \
- ${PTHREAD_CFLAGS} \
-DBUILDING_LIBMEMCACHED
+libmemcached_libmemcachedprotocol_la_CXXFLAGS+= ${PTHREAD_CFLAGS}
-libmemcached_libmemcachedprotocol_la_LDFLAGS= ${AM_LDFLAGS} ${PTHREAD_LIBS} -version-info ${MEMCACHED_PROTOCAL_LIBRARY_VERSION}
+libmemcached_libmemcachedprotocol_la_LIBADD= ${PTHREAD_LIBS}
+libmemcached_libmemcachedprotocol_la_LDFLAGS= ${AM_LDFLAGS}
+libmemcached_libmemcachedprotocol_la_LDFLAGS+= -version-info ${MEMCACHED_PROTOCAL_LIBRARY_VERSION}
+++ /dev/null
-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * Libmemcached library
- *
- * Copyright (C) 2011 Data Differential, http://datadifferential.com/
- * Copyright (C) 2006-2009 Brian Aker All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <libmemcached/common.h>
-#include <iso646.h>
-
-void memcached_set_sasl_callbacks(memcached_st *ptr,
- const sasl_callback_t *callbacks)
-{
- ptr->sasl.callbacks= callbacks;
- ptr->sasl.is_allocated= false;
-}
-
-const sasl_callback_t *memcached_get_sasl_callbacks(memcached_st *ptr)
-{
- return ptr->sasl.callbacks;
-}
-
-/**
- * Resolve the names for both ends of a connection
- * @param fd socket to check
- * @param laddr local address (out)
- * @param raddr remote address (out)
- * @return true on success false otherwise (errno contains more info)
- */
-static memcached_return_t resolve_names(int fd, char *laddr, size_t laddr_length, char *raddr, size_t raddr_length)
-{
- char host[NI_MAXHOST];
- char port[NI_MAXSERV];
- struct sockaddr_storage saddr;
- socklen_t salen= sizeof(saddr);
-
- if (getsockname(fd, (struct sockaddr *)&saddr, &salen) < 0)
- {
- return MEMCACHED_ERRNO;
- }
-
- if (getnameinfo((struct sockaddr *)&saddr, salen, host, sizeof(host), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) < 0)
- {
- return MEMCACHED_HOST_LOOKUP_FAILURE;
- }
-
- (void)snprintf(laddr, laddr_length, "%s;%s", host, port);
- salen= sizeof(saddr);
-
- if (getpeername(fd, (struct sockaddr *)&saddr, &salen) < 0)
- {
- return MEMCACHED_ERRNO;
- }
-
- if (getnameinfo((struct sockaddr *)&saddr, salen, host, sizeof(host),
- port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) < 0)
- {
- return MEMCACHED_HOST_LOOKUP_FAILURE;
- }
-
- (void)snprintf(raddr, raddr_length, "%s;%s", host, port);
-
- return MEMCACHED_SUCCESS;
-}
-
-memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *server)
-{
- /* SANITY CHECK: SASL can only be used with the binary protocol */
- if (!server->root->flags.binary_protocol)
- return MEMCACHED_FAILURE;
-
- /* Try to get the supported mech from the server. Servers without SASL
- * support will return UNKNOWN COMMAND, so we can just treat that
- * as authenticated
- */
- protocol_binary_request_no_extras request= {
- .message.header.request= {
- .magic= PROTOCOL_BINARY_REQ,
- .opcode= PROTOCOL_BINARY_CMD_SASL_LIST_MECHS
- }
- };
-
- if (memcached_io_write(server, request.bytes,
- sizeof(request.bytes), 1) != sizeof(request.bytes))
- {
- return MEMCACHED_WRITE_FAILURE;
- }
-
- memcached_server_response_increment(server);
-
- char mech[MEMCACHED_MAX_BUFFER];
- memcached_return_t rc= memcached_response(server, mech, sizeof(mech), NULL);
- if (memcached_failed(rc))
- {
- if (rc == MEMCACHED_PROTOCOL_ERROR)
- {
- /* If the server doesn't support SASL it will return PROTOCOL_ERROR.
- * This error may also be returned for other errors, but let's assume
- * that the server don't support SASL and treat it as success and
- * let the client fail with the next operation if the error was
- * caused by another problem....
- */
- rc= MEMCACHED_SUCCESS;
- }
-
- return rc;
- }
-
- /* set ip addresses */
- char laddr[NI_MAXHOST + NI_MAXSERV];
- char raddr[NI_MAXHOST + NI_MAXSERV];
-
- if (memcached_failed(rc= resolve_names(server->fd, laddr, sizeof(laddr), raddr, sizeof(raddr))))
- {
- return rc;
- }
-
- sasl_conn_t *conn;
- int ret= sasl_client_new("memcached", server->hostname, laddr, raddr, server->root->sasl.callbacks, 0, &conn);
- if (ret != SASL_OK)
- {
- return MEMCACHED_AUTH_PROBLEM;
- }
-
- const char *data;
- const char *chosenmech;
- unsigned int len;
- ret= sasl_client_start(conn, mech, NULL, &data, &len, &chosenmech);
-
- if (ret != SASL_OK && ret != SASL_CONTINUE)
- {
- rc= MEMCACHED_AUTH_PROBLEM;
- goto end;
- }
-
- uint16_t keylen= (uint16_t)strlen(chosenmech);
- request.message.header.request.opcode= PROTOCOL_BINARY_CMD_SASL_AUTH;
- request.message.header.request.keylen= htons(keylen);
- request.message.header.request.bodylen= htonl(len + keylen);
-
- do {
- /* send the packet */
-
- struct libmemcached_io_vector_st vector[]=
- {
- { .length= sizeof(request.bytes), .buffer= request.bytes },
- { .length= keylen, .buffer= chosenmech },
- { .length= len, .buffer= data }
- };
-
- if (memcached_io_writev(server, vector, 3, true) == -1)
- {
- rc= MEMCACHED_WRITE_FAILURE;
- goto end;
- }
- memcached_server_response_increment(server);
-
- /* read the response */
- rc= memcached_response(server, NULL, 0, NULL);
- if (rc != MEMCACHED_AUTH_CONTINUE)
- {
- goto end;
- }
-
- ret= sasl_client_step(conn, memcached_result_value(&server->root->result),
- (unsigned int)memcached_result_length(&server->root->result),
- NULL, &data, &len);
-
- if (ret != SASL_OK && ret != SASL_CONTINUE)
- {
- rc= MEMCACHED_AUTH_PROBLEM;
- goto end;
- }
-
- request.message.header.request.opcode= PROTOCOL_BINARY_CMD_SASL_STEP;
- request.message.header.request.bodylen= htonl(len + keylen);
- } while (true);
-
-end:
- /* Release resources */
- sasl_dispose(&conn);
-
- return rc;
-}
-
-static int get_username(void *context, int id, const char **result,
- unsigned int *len)
-{
- if (!context || !result || (id != SASL_CB_USER && id != SASL_CB_AUTHNAME))
- {
- return SASL_BADPARAM;
- }
-
- *result= context;
- if (len)
- {
- *len= (unsigned int)strlen(*result);
- }
-
- return SASL_OK;
-}
-
-static int get_password(sasl_conn_t *conn, void *context, int id,
- sasl_secret_t **psecret)
-{
- if (!conn || ! psecret || id != SASL_CB_PASS)
- {
- return SASL_BADPARAM;
- }
-
- *psecret= context;
-
- return SASL_OK;
-}
-
-memcached_return_t memcached_set_sasl_auth_data(memcached_st *ptr,
- const char *username,
- const char *password)
-{
- if (ptr == NULL || username == NULL ||
- password == NULL || ptr->sasl.callbacks != NULL)
- {
- return MEMCACHED_FAILURE;
- }
-
- sasl_callback_t *callbacks= libmemcached_calloc(ptr, 4, sizeof(sasl_callback_t));
- size_t password_length= strlen(password);
- size_t username_length= strlen(username);
- char *name= libmemcached_malloc(ptr, username_length +1);
- sasl_secret_t *secret= libmemcached_malloc(ptr, password_length +1 + sizeof(sasl_secret_t));
-
- if (callbacks == NULL || name == NULL || secret == NULL)
- {
- libmemcached_free(ptr, callbacks);
- libmemcached_free(ptr, name);
- libmemcached_free(ptr, secret);
- return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
- }
-
- secret->len= password_length;
- memcpy(secret->data, password, password_length);
- secret->data[password_length]= 0;
-
- callbacks[0].id= SASL_CB_USER;
- callbacks[0].proc= get_username;
- callbacks[0].context= strncpy(name, username, username_length +1);
- callbacks[1].id= SASL_CB_AUTHNAME;
- callbacks[1].proc= get_username;
- callbacks[1].context= name;
- callbacks[2].id= SASL_CB_PASS;
- callbacks[2].proc= get_password;
- callbacks[2].context= secret;
- callbacks[3].id= SASL_CB_LIST_END;
-
- ptr->sasl.callbacks= callbacks;
- ptr->sasl.is_allocated= true;
-
- return MEMCACHED_SUCCESS;
-}
-
-memcached_return_t memcached_destroy_sasl_auth_data(memcached_st *ptr)
-{
- if (ptr == NULL || ptr->sasl.callbacks == NULL)
- {
- return MEMCACHED_FAILURE;
- }
-
- if (ptr->sasl.is_allocated)
- {
- libmemcached_free(ptr, ptr->sasl.callbacks[0].context);
- libmemcached_free(ptr, ptr->sasl.callbacks[2].context);
- libmemcached_free(ptr, (void*)ptr->sasl.callbacks);
- ptr->sasl.is_allocated= false;
- }
-
- ptr->sasl.callbacks= NULL;
-
- return MEMCACHED_SUCCESS;
-}
-
-memcached_return_t memcached_clone_sasl(memcached_st *clone, const memcached_st *source)
-{
-
- if (source->sasl.callbacks == NULL)
- {
- return MEMCACHED_SUCCESS;
- }
-
- /* Hopefully we are using our own callback mechanisms.. */
- if (source->sasl.callbacks[0].id == SASL_CB_USER &&
- source->sasl.callbacks[0].proc == get_username &&
- source->sasl.callbacks[1].id == SASL_CB_AUTHNAME &&
- source->sasl.callbacks[1].proc == get_username &&
- source->sasl.callbacks[2].id == SASL_CB_PASS &&
- source->sasl.callbacks[2].proc == get_password &&
- source->sasl.callbacks[3].id == SASL_CB_LIST_END)
- {
- sasl_secret_t *secret= source->sasl.callbacks[2].context;
- return memcached_set_sasl_auth_data(clone,
- source->sasl.callbacks[0].context,
- (const char*)secret->data);
- }
-
- /*
- * But we're not. It may work if we know what the user tries to pass
- * into the list, but if we don't know the ID we don't know how to handle
- * the context...
- */
- size_t total= 0;
-
- while (source->sasl.callbacks[total].id != SASL_CB_LIST_END)
- {
- switch (source->sasl.callbacks[total].id)
- {
- case SASL_CB_USER:
- case SASL_CB_AUTHNAME:
- case SASL_CB_PASS:
- break;
- default:
- /* I don't know how to deal with this... */
- return MEMCACHED_NOT_SUPPORTED;
- }
-
- ++total;
- }
-
- sasl_callback_t *callbacks= libmemcached_calloc(clone, total + 1, sizeof(sasl_callback_t));
- if (callbacks == NULL)
- {
- return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
- }
- memcpy(callbacks, source->sasl.callbacks, (total + 1) * sizeof(sasl_callback_t));
-
- /* Now update the context... */
- for (size_t x= 0; x < total; ++x)
- {
- if (callbacks[x].id == SASL_CB_USER || callbacks[x].id == SASL_CB_AUTHNAME)
- {
- callbacks[x].context= libmemcached_malloc(clone, strlen(source->sasl.callbacks[x].context));
-
- if (callbacks[x].context == NULL)
- {
- /* Failed to allocate memory, clean up previously allocated memory */
- for (size_t y= 0; y < x; ++y)
- {
- libmemcached_free(clone, clone->sasl.callbacks[y].context);
- }
-
- libmemcached_free(clone, callbacks);
- return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
- }
- strncpy(callbacks[x].context, source->sasl.callbacks[x].context, sizeof(callbacks[x].context));
- }
- else
- {
- sasl_secret_t *src = source->sasl.callbacks[x].context;
- sasl_secret_t *n = libmemcached_malloc(clone, src->len + 1 + sizeof(*n));
- if (n == NULL)
- {
- /* Failed to allocate memory, clean up previously allocated memory */
- for (size_t y= 0; y < x; ++y)
- {
- libmemcached_free(clone, clone->sasl.callbacks[y].context);
- }
-
- libmemcached_free(clone, callbacks);
- return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
- }
- memcpy(n, src, src->len + 1 + sizeof(*n));
- callbacks[x].context= n;
- }
- }
-
- clone->sasl.callbacks= callbacks;
- clone->sasl.is_allocated= true;
-
- return MEMCACHED_SUCCESS;
-}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached library
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <libmemcached/common.h>
+#include <cassert>
+
+#if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT
+
+#include <sasl/sasl.h>
+
+void memcached_set_sasl_callbacks(memcached_st *ptr,
+ const sasl_callback_t *callbacks)
+{
+ ptr->sasl.callbacks= const_cast<sasl_callback_t *>(callbacks);
+ ptr->sasl.is_allocated= false;
+}
+
+sasl_callback_t *memcached_get_sasl_callbacks(memcached_st *ptr)
+{
+ return ptr->sasl.callbacks;
+}
+
+/**
+ * Resolve the names for both ends of a connection
+ * @param fd socket to check
+ * @param laddr local address (out)
+ * @param raddr remote address (out)
+ * @return true on success false otherwise (errno contains more info)
+ */
+static memcached_return_t resolve_names(memcached_server_st& server, char *laddr, size_t laddr_length, char *raddr, size_t raddr_length)
+{
+ char host[NI_MAXHOST];
+ char port[NI_MAXSERV];
+ struct sockaddr_storage saddr;
+ socklen_t salen= sizeof(saddr);
+
+ if (getsockname(server.fd, (struct sockaddr *)&saddr, &salen) < 0)
+ {
+ return memcached_set_errno(server, MEMCACHED_ERRNO, MEMCACHED_AT);
+ }
+
+ if (getnameinfo((struct sockaddr *)&saddr, salen, host, sizeof(host), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) < 0)
+ {
+ return MEMCACHED_HOST_LOOKUP_FAILURE;
+ }
+
+ (void)snprintf(laddr, laddr_length, "%s;%s", host, port);
+ salen= sizeof(saddr);
+
+ if (getpeername(server.fd, (struct sockaddr *)&saddr, &salen) < 0)
+ {
+ return memcached_set_errno(server, MEMCACHED_ERRNO, MEMCACHED_AT);
+ }
+
+ if (getnameinfo((struct sockaddr *)&saddr, salen, host, sizeof(host),
+ port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) < 0)
+ {
+ return memcached_set_error(server, MEMCACHED_HOST_LOOKUP_FAILURE, MEMCACHED_AT);
+ }
+
+ (void)snprintf(raddr, raddr_length, "%s;%s", host, port);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *server)
+{
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+ {
+ return MEMCACHED_NOT_SUPPORTED;
+ }
+
+ if (server == NULL)
+ {
+ return MEMCACHED_INVALID_ARGUMENTS;
+ }
+
+ /* SANITY CHECK: SASL can only be used with the binary protocol */
+ if (server->root->flags.binary_protocol == false)
+ {
+ return MEMCACHED_PROTOCOL_ERROR;
+ }
+
+ /* Try to get the supported mech from the server. Servers without SASL
+ * support will return UNKNOWN COMMAND, so we can just treat that
+ * as authenticated
+ */
+ protocol_binary_request_no_extras request= { };
+ request.message.header.request.magic= PROTOCOL_BINARY_REQ;
+ request.message.header.request.opcode= PROTOCOL_BINARY_CMD_SASL_LIST_MECHS;
+
+ if (memcached_io_write(server, request.bytes,
+ sizeof(request.bytes), 1) != sizeof(request.bytes))
+ {
+ return MEMCACHED_WRITE_FAILURE;
+ }
+
+ memcached_server_response_increment(server);
+
+ char mech[MEMCACHED_MAX_BUFFER];
+ memcached_return_t rc= memcached_response(server, mech, sizeof(mech), NULL);
+ if (memcached_failed(rc))
+ {
+ if (rc == MEMCACHED_PROTOCOL_ERROR)
+ {
+ /* If the server doesn't support SASL it will return PROTOCOL_ERROR.
+ * This error may also be returned for other errors, but let's assume
+ * that the server don't support SASL and treat it as success and
+ * let the client fail with the next operation if the error was
+ * caused by another problem....
+ */
+ rc= MEMCACHED_SUCCESS;
+ }
+
+ return rc;
+ }
+
+ /* set ip addresses */
+ char laddr[NI_MAXHOST + NI_MAXSERV];
+ char raddr[NI_MAXHOST + NI_MAXSERV];
+
+ if (memcached_failed(rc= resolve_names(*server, laddr, sizeof(laddr), raddr, sizeof(raddr))))
+ {
+ return rc;
+ }
+
+ int ret;
+ if ((ret= sasl_client_init(NULL)) != SASL_OK)
+ {
+ const char *sasl_error_msg= sasl_errstring(ret, NULL, NULL);
+ return memcached_set_error(*server, MEMCACHED_AUTH_PROBLEM, MEMCACHED_AT,
+ memcached_string_make_from_cstr(sasl_error_msg));
+ }
+
+ sasl_conn_t *conn;
+ 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);
+ return memcached_set_error(*server, MEMCACHED_AUTH_PROBLEM, MEMCACHED_AT,
+ memcached_string_make_from_cstr(sasl_error_msg));
+ }
+
+ const char *data;
+ const char *chosenmech;
+ unsigned int len;
+ ret= sasl_client_start(conn, mech, NULL, &data, &len, &chosenmech);
+ if (ret != SASL_OK and ret != SASL_CONTINUE)
+ {
+ const char *sasl_error_msg= sasl_errstring(ret, NULL, NULL);
+ return memcached_set_error(*server, MEMCACHED_AUTH_PROBLEM, MEMCACHED_AT,
+ memcached_string_make_from_cstr(sasl_error_msg));
+ }
+ uint16_t keylen= (uint16_t)strlen(chosenmech);
+ request.message.header.request.opcode= PROTOCOL_BINARY_CMD_SASL_AUTH;
+ request.message.header.request.keylen= htons(keylen);
+ request.message.header.request.bodylen= htonl(len + keylen);
+
+ do {
+ /* send the packet */
+
+ struct libmemcached_io_vector_st vector[]=
+ {
+ { sizeof(request.bytes), request.bytes },
+ { keylen, chosenmech },
+ { len, data }
+ };
+
+ if (memcached_io_writev(server, vector, 3, true) == -1)
+ {
+ rc= MEMCACHED_WRITE_FAILURE;
+ break;
+ }
+ memcached_server_response_increment(server);
+
+ /* read the response */
+ rc= memcached_response(server, NULL, 0, NULL);
+ if (rc != MEMCACHED_AUTH_CONTINUE)
+ {
+ break;
+ }
+
+ ret= sasl_client_step(conn, memcached_result_value(&server->root->result),
+ (unsigned int)memcached_result_length(&server->root->result),
+ NULL, &data, &len);
+
+ if (ret != SASL_OK && ret != SASL_CONTINUE)
+ {
+ rc= MEMCACHED_AUTH_PROBLEM;
+ break;
+ }
+
+ request.message.header.request.opcode= PROTOCOL_BINARY_CMD_SASL_STEP;
+ request.message.header.request.bodylen= htonl(len + keylen);
+ } while (true);
+
+ /* Release resources */
+ sasl_dispose(&conn);
+
+ return memcached_set_error(*server, rc, MEMCACHED_AT);
+}
+
+static int get_username(void *context, int id, const char **result, unsigned int *len)
+{
+ if (!context || !result || (id != SASL_CB_USER && id != SASL_CB_AUTHNAME))
+ {
+ return SASL_BADPARAM;
+ }
+
+ *result= (char *)context;
+ if (len)
+ {
+ *len= (unsigned int)strlen(*result);
+ }
+
+ return SASL_OK;
+}
+
+static int get_password(sasl_conn_t *conn, void *context, int id,
+ sasl_secret_t **psecret)
+{
+ if (!conn || ! psecret || id != SASL_CB_PASS)
+ {
+ return SASL_BADPARAM;
+ }
+
+ *psecret= (sasl_secret_t *)context;
+
+ return SASL_OK;
+}
+
+memcached_return_t memcached_set_sasl_auth_data(memcached_st *ptr,
+ const char *username,
+ const char *password)
+{
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+ {
+ return MEMCACHED_NOT_SUPPORTED;
+ }
+
+ if (ptr == NULL or username == NULL or password == NULL)
+ {
+ return MEMCACHED_INVALID_ARGUMENTS;
+ }
+
+ memcached_destroy_sasl_auth_data(ptr);
+
+ sasl_callback_t *callbacks= (sasl_callback_t*)libmemcached_calloc(ptr, 4, sizeof(sasl_callback_t));
+ size_t password_length= strlen(password);
+ size_t username_length= strlen(username);
+ char *name= (char *)libmemcached_malloc(ptr, username_length +1);
+ sasl_secret_t *secret= (sasl_secret_t*)libmemcached_malloc(ptr, password_length +1 + sizeof(sasl_secret_t));
+
+ if (callbacks == NULL or name == NULL or secret == NULL)
+ {
+ libmemcached_free(ptr, callbacks);
+ libmemcached_free(ptr, name);
+ libmemcached_free(ptr, secret);
+ return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT);
+ }
+
+ secret->len= password_length;
+ memcpy(secret->data, password, password_length);
+ secret->data[password_length]= 0;
+
+ callbacks[0].id= SASL_CB_USER;
+ callbacks[0].proc= (int (*)())get_username;
+ callbacks[0].context= strncpy(name, username, username_length +1);
+ callbacks[1].id= SASL_CB_AUTHNAME;
+ callbacks[1].proc= (int (*)())get_username;
+ callbacks[1].context= name;
+ callbacks[2].id= SASL_CB_PASS;
+ callbacks[2].proc= (int (*)())get_password;
+ callbacks[2].context= secret;
+ callbacks[3].id= SASL_CB_LIST_END;
+
+ ptr->sasl.callbacks= callbacks;
+ ptr->sasl.is_allocated= true;
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return_t memcached_destroy_sasl_auth_data(memcached_st *ptr)
+{
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+ {
+ return MEMCACHED_NOT_SUPPORTED;
+ }
+
+ if (ptr == NULL)
+ {
+ return MEMCACHED_INVALID_ARGUMENTS;
+ }
+
+ if (ptr->sasl.callbacks == NULL)
+ {
+ return MEMCACHED_SUCCESS;
+ }
+
+ if (ptr->sasl.is_allocated)
+ {
+ libmemcached_free(ptr, ptr->sasl.callbacks[0].context);
+ libmemcached_free(ptr, ptr->sasl.callbacks[2].context);
+ libmemcached_free(ptr, (void*)ptr->sasl.callbacks);
+ ptr->sasl.is_allocated= false;
+ }
+
+ ptr->sasl.callbacks= NULL;
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return_t memcached_clone_sasl(memcached_st *clone, const memcached_st *source)
+{
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+ {
+ return MEMCACHED_NOT_SUPPORTED;
+ }
+
+ if (clone == NULL or source == NULL)
+ {
+ return MEMCACHED_INVALID_ARGUMENTS;
+ }
+
+ if (source->sasl.callbacks == NULL)
+ {
+ return MEMCACHED_SUCCESS;
+ }
+
+ /* Hopefully we are using our own callback mechanisms.. */
+ if (source->sasl.callbacks[0].id == SASL_CB_USER &&
+ source->sasl.callbacks[0].proc == (int (*)())get_username &&
+ source->sasl.callbacks[1].id == SASL_CB_AUTHNAME &&
+ source->sasl.callbacks[1].proc == (int (*)())get_username &&
+ source->sasl.callbacks[2].id == SASL_CB_PASS &&
+ source->sasl.callbacks[2].proc == (int (*)())get_password &&
+ source->sasl.callbacks[3].id == SASL_CB_LIST_END)
+ {
+ sasl_secret_t *secret= (sasl_secret_t *)source->sasl.callbacks[2].context;
+ return memcached_set_sasl_auth_data(clone,
+ (const char*)source->sasl.callbacks[0].context,
+ (const char*)secret->data);
+ }
+
+ /*
+ * But we're not. It may work if we know what the user tries to pass
+ * into the list, but if we don't know the ID we don't know how to handle
+ * the context...
+ */
+ size_t total= 0;
+
+ while (source->sasl.callbacks[total].id != SASL_CB_LIST_END)
+ {
+ switch (source->sasl.callbacks[total].id)
+ {
+ case SASL_CB_USER:
+ case SASL_CB_AUTHNAME:
+ case SASL_CB_PASS:
+ break;
+ default:
+ /* I don't know how to deal with this... */
+ return MEMCACHED_NOT_SUPPORTED;
+ }
+
+ ++total;
+ }
+
+ sasl_callback_t *callbacks= (sasl_callback_t*)libmemcached_calloc(clone, total +1, sizeof(sasl_callback_t));
+ if (callbacks == NULL)
+ {
+ return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+ }
+ memcpy(callbacks, source->sasl.callbacks, (total + 1) * sizeof(sasl_callback_t));
+
+ /* Now update the context... */
+ for (size_t x= 0; x < total; ++x)
+ {
+ if (callbacks[x].id == SASL_CB_USER || callbacks[x].id == SASL_CB_AUTHNAME)
+ {
+ callbacks[x].context= (sasl_callback_t*)libmemcached_malloc(clone, strlen((const char*)source->sasl.callbacks[x].context));
+
+ if (callbacks[x].context == NULL)
+ {
+ /* Failed to allocate memory, clean up previously allocated memory */
+ for (size_t y= 0; y < x; ++y)
+ {
+ libmemcached_free(clone, clone->sasl.callbacks[y].context);
+ }
+
+ libmemcached_free(clone, callbacks);
+ return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+ }
+ strncpy((char*)callbacks[x].context, (const char*)source->sasl.callbacks[x].context, sizeof(callbacks[x].context));
+ }
+ else
+ {
+ sasl_secret_t *src= (sasl_secret_t *)source->sasl.callbacks[x].context;
+ sasl_secret_t *n= (sasl_secret_t*)libmemcached_malloc(clone, src->len + 1 + sizeof(*n));
+ if (n == NULL)
+ {
+ /* Failed to allocate memory, clean up previously allocated memory */
+ for (size_t y= 0; y < x; ++y)
+ {
+ libmemcached_free(clone, clone->sasl.callbacks[y].context);
+ }
+
+ libmemcached_free(clone, callbacks);
+ return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+ }
+ memcpy(n, src, src->len + 1 + sizeof(*n));
+ callbacks[x].context= n;
+ }
+ }
+
+ clone->sasl.callbacks= callbacks;
+ clone->sasl.is_allocated= true;
+
+ return MEMCACHED_SUCCESS;
+}
+
+#else
+
+void memcached_set_sasl_callbacks(memcached_st *, const sasl_callback_t *)
+{
+}
+
+sasl_callback_t *memcached_get_sasl_callbacks(memcached_st *)
+{
+ return NULL;
+}
+
+memcached_return_t memcached_set_sasl_auth_data(memcached_st *, const char *, const char *)
+{
+ return MEMCACHED_NOT_SUPPORTED;
+}
+
+memcached_return_t memcached_clone_sasl(memcached_st *, const memcached_st *)
+{
+ return MEMCACHED_NOT_SUPPORTED;
+}
+
+#endif
#pragma once
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
+#if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT
#include <sasl/sasl.h>
+#else
+#define sasl_callback_t void
+#endif
#ifdef __cplusplus
extern "C" {
LIBMEMCACHED_API
-const sasl_callback_t *memcached_get_sasl_callbacks(memcached_st *ptr);
+sasl_callback_t *memcached_get_sasl_callbacks(memcached_st *ptr);
LIBMEMCACHED_LOCAL
memcached_return_t memcached_clone_sasl(memcached_st *clone, const memcached_st *source);
}
#endif
-#endif /* LIBMEMCACHED_WITH_SASL_SUPPORT */
-
struct memcached_sasl_st {
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
- const sasl_callback_t *callbacks;
-#else
- const void *callbacks;
-#endif
- /*
- ** Did we allocate data inside the callbacks, or did the user
- ** supply that.
- */
- bool is_allocated;
+ sasl_callback_t *callbacks;
+ /*
+ ** Did we allocate data inside the callbacks, or did the user
+ ** supply that.
+ */
+ bool is_allocated;
};
libmemcached/util/ping.cc \
libmemcached/util/pool.cc \
libmemcached/util/version.cc
-libmemcached_libmemcachedutil_la_CFLAGS= \
- ${AM_CFLAGS} \
- ${NO_CONVERSION} \
- ${PTHREAD_CFLAGS} \
- -DBUILDING_LIBMEMCACHED
libmemcached_libmemcachedutil_la_CXXFLAGS= \
${AM_CXXFLAGS} \
${NO_CONVERSION} \
- ${PTHREAD_CFLAGS} \
-DBUILDING_LIBMEMCACHED
-libmemcached_libmemcachedutil_la_LIBADD= libmemcached/libmemcached.la ${PTHREAD_LIBS}
+libmemcached_libmemcachedutil_la_CXXFLAGS+= ${PTHREAD_CFLAGS}
+libmemcached_libmemcachedutil_la_LIBADD= libmemcached/libmemcached.la
+libmemcached_libmemcachedutil_la_LIBADD+= ${PTHREAD_LIBS}
libmemcached_libmemcachedutil_la_LDFLAGS= ${AM_LDFLAGS} -version-info ${MEMCACHED_UTIL_LIBRARY_VERSION}
libmemcached_libmemcachedutil_la_DEPENDENCIES= libmemcached/libmemcached.la
return pid;
}
+pid_t libmemcached_util_getpid2(const char *hostname, in_port_t port, const char *username, const char *password, memcached_return_t *ret)
+{
+ if (username == NULL)
+ {
+ return libmemcached_util_getpid(hostname, port, ret);
+ }
+
+ pid_t pid= -1;
+
+ memcached_return_t unused;
+ if (not ret)
+ ret= &unused;
+
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+ {
+ *ret= MEMCACHED_NOT_SUPPORTED;
+ return pid;
+ }
+
+ memcached_st *memc_ptr= memcached_create(NULL);
+ if (not memc_ptr)
+ {
+ *ret= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+ 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);
+ return false;
+ }
+
+
+ memcached_return_t rc= memcached_server_add(memc_ptr, hostname, port);
+ if (memcached_success(rc))
+ {
+ memcached_stat_st *stat= memcached_stat(memc_ptr, NULL, &rc);
+ if (memcached_success(rc) and stat and stat->pid != -1)
+ {
+ pid= stat->pid;
+ }
+ else if (memcached_success(rc))
+ {
+ rc= MEMCACHED_UNKNOWN_STAT_KEY; // Something went wrong if this happens
+ }
+ else if (rc == MEMCACHED_SOME_ERRORS) // Generic answer, we will now find the specific reason (if one exists)
+ {
+ memcached_server_instance_st instance=
+ memcached_server_instance_by_position(memc_ptr, 0);
+
+ assert_msg(instance and instance->error_messages, " ");
+ if (instance and instance->error_messages)
+ {
+ rc= memcached_server_error_return(instance);
+ }
+ }
+
+ memcached_stat_free(memc_ptr, stat);
+ }
+ memcached_free(memc_ptr);
+
+ *ret= rc;
+
+ return pid;
+}
LIBMEMCACHED_API
pid_t libmemcached_util_getpid(const char *hostname, in_port_t port, memcached_return_t *ret);
+LIBMEMCACHED_API
+pid_t libmemcached_util_getpid2(const char *hostname, in_port_t port, const char *username, const char *password, memcached_return_t *ret);
+
#ifdef __cplusplus
}
#endif
#include <libmemcached/common.h>
#include <libmemcached/memcached_util.h>
-
bool libmemcached_util_ping(const char *hostname, in_port_t port, memcached_return_t *ret)
{
memcached_return_t unused;
return memcached_success(rc);
}
+
+bool libmemcached_util_ping2(const char *hostname, in_port_t port, const char *username, const char *password, memcached_return_t *ret)
+{
+ if (username == NULL)
+ {
+ return libmemcached_util_ping(hostname, port, ret);
+ }
+
+ memcached_return_t unused;
+ if (not ret)
+ ret= &unused;
+
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+ {
+ *ret= MEMCACHED_NOT_SUPPORTED;
+ return false;
+ }
+
+ memcached_st *memc_ptr= memcached_create(NULL);
+ if (not memc_ptr)
+ {
+ *ret= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+ 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);
+ return false;
+ }
+
+ memcached_return_t rc= memcached_server_add(memc_ptr, hostname, port);
+ if (memcached_success(rc))
+ {
+ rc= memcached_version(memc_ptr);
+ }
+
+ if (memcached_failed(rc) and rc == MEMCACHED_SOME_ERRORS)
+ {
+ memcached_server_instance_st instance=
+ memcached_server_instance_by_position(memc_ptr, 0);
+
+ assert_msg(instance and instance->error_messages, " ");
+ if (instance and instance->error_messages)
+ {
+ rc= memcached_server_error_return(instance);
+ }
+ }
+ memcached_free(memc_ptr);
+
+ *ret= rc;
+
+ return memcached_success(rc);
+}
LIBMEMCACHED_API
bool libmemcached_util_ping(const char *hostname, in_port_t port, memcached_return_t *ret);
+LIBMEMCACHED_API
+bool libmemcached_util_ping2(const char *hostname, in_port_t port, const char *username, const char *password, memcached_return_t *ret);
+
#ifdef __cplusplus
}
#endif
noinst_LTLIBRARIES+= libmemcachedinternal/libmemcachedutilinternal.la
libmemcachedinternal_libmemcachedutilinternal_la_SOURCES= $(libmemcached_libmemcachedutil_la_SOURCES)
-libmemcachedinternal_libmemcachedutilinternal_la_CFLAGS= \
- ${AM_CFLAGS} \
- ${NO_CONVERSION} \
- ${PTHREAD_CFLAGS} \
- -DBUILDING_LIBMEMCACHEDINTERNAL
libmemcachedinternal_libmemcachedutilinternal_la_CXXFLAGS= \
${AM_CXXFLAGS} \
${NO_CONVERSION} \
- ${PTHREAD_CFLAGS} \
-DBUILDING_LIBMEMCACHEDINTERNAL
+libmemcachedinternal_libmemcachedutilinternal_la_CXXFLAGS+= ${PTHREAD_CFLAGS}
libmemcachedinternal_libmemcachedutilinternal_la_LIBADD= libmemcachedinternal/libmemcachedinternal.la ${PTHREAD_LIBS}
-libmemcachedinternal_libmemcachedutilinternal_la_LDFLAGS= ${AM_LDFLAGS} -version-info ${MEMCACHED_UTIL_LIBRARY_VERSION}
-libmemcachedinternal_libmemcachedutilinternal_la_DEPENDENCIES= libmemcached/libmemcached.la
+libmemcachedinternal_libmemcachedutilinternal_la_DEPENDENCIES= libmemcachedinternal/libmemcachedinternal.la
#include <libtest/common.h>
+
#include <libtest/blobslap_worker.h>
#include <libtest/killpid.h>
public:
BlobslapWorker(in_port_t port_arg) :
Server("localhost", port_arg)
- { }
+ {
+ set_pid_file();
+ }
pid_t get_pid(bool error_is_ok)
{
- if (not pid_file().empty())
+ if (pid_file().empty())
{
- Wait wait(pid_file(), 0);
+ Error << "pid_file was empty";
+ return -1;
+ }
- if (error_is_ok and not wait.successful())
- {
- Error << "Pidfile was not found:" << pid_file();
- return -1;
+ Wait wait(pid_file(), 0);
- return get_pid_from_file(pid_file());
- }
+ if (error_is_ok and not wait.successful())
+ {
+ Error << "Pidfile was not found:" << pid_file();
+ return -1;
+ }
+
+ std::stringstream error_message;
+ pid_t ret= get_pid_from_file(pid_file(), error_message);
+
+ if (error_is_ok and is_pid_valid(ret) == false)
+ {
+ Error << error_message.str();
}
- return -1;
+ return ret;
}
bool ping()
return false;
}
- pid_t local_pid= get_pid_from_file(pid_file());
- if (local_pid <= 0)
+ std::stringstream error_message;
+ pid_t local_pid= get_pid_from_file(pid_file(), error_message);
+ if (is_pid_valid(local_pid) == false)
{
+ Error << error_message.str();
return false;
}
+ // Use kill to determine is the process exist
if (::kill(local_pid, 0) == 0)
{
return true;
const char *log_file_option()
{
- return NULL;
+ return "--log-file=";
}
const char *port_option()
#include <libtest/common.h>
-#include <libtest/cmdline.h>
-
using namespace libtest;
#include <cstdlib>
#include <string>
#include <sstream>
+namespace libtest {
+
bool exec_cmdline(const std::string& executable, const char *args[])
{
std::stringstream arg_buffer;
- arg_buffer << "./libtool --mode=execute ";
+ arg_buffer << libtool();
if (getenv("LIBTEST_TEST_ENVIRONMENT"))
{
return true;
}
+
+const char *gearmand_binary()
+{
+ return GEARMAND_BINARY;
+}
+
+} // namespace exec_cmdline
#pragma once
+namespace libtest {
+
bool exec_cmdline(const std::string& executable, const char *args[]);
+
+const char *gearmand_binary();
+
+}
*/
/*
- Common include file for libmemached
+ Common include file for libtest
*/
#pragma once
#include <fnmatch.h>
#endif
+static inline bool is_pid_valid(const pid_t pid)
+{
+ return (pid > 1) ? true : false;
+}
+
+#include <libtest/gearmand.h>
+#include <libtest/blobslap_worker.h>
+#include <libtest/memcached.h>
+
+#include <libtest/libtool.hpp>
+
#include <libtest/test.hpp>
#include <typeinfo>
#include <libtest/strerror.h>
+
+#if defined(HAVE_LIBMEMCACHED) && HAVE_LIBMEMCACHED
#include <libmemcached/memcached.h>
+#endif
+
+#if defined(HAVE_LIBGEARMAN) && HAVE_LIBGEARMAN
+#include <libgearman/gearman.h>
+#endif
namespace libtest {
}
template <class T_comparable>
-bool _compare(const char *file, int line, const char *func, T_comparable __expected, T_comparable __actual)
+bool _compare(const char *file, int line, const char *func, const T_comparable __expected, const T_comparable __actual)
{
if (__expected != __actual)
{
- if (typeid(__expected) == typeid(memcached_return_t))
+ 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
+ << "\"";
+ }
+#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)) << "\"";
}
- else if (typeid(__expected) == typeid(test_return_t))
+#endif
+#if defined(HAVE_LIBGEARMAN) && HAVE_LIBGEARMAN
+ else if (typeid(__expected) == typeid(gearman_return_t))
{
libtest::stream::make_cerr(file, line, func) << "Expected \""
- << test_strerror(test_return_t(__expected))
+ << gearman_strerror(gearman_return_t(__expected))
<< "\" got \""
- << test_strerror(test_return_t(__actual)) << "\"";
+ << gearman_strerror(gearman_return_t(__actual)) << "\"";
}
+#endif
else
{
libtest::stream::make_cerr(file, line, func) << "Expected \"" << __expected << "\" got \"" << __actual << "\"";
{
_servers.set_socket();
}
+
+ void set_sasl(const std::string& username_arg, const std::string& password_arg)
+ {
+ _servers.set_sasl(username_arg, password_arg);
+ }
/**
Runner represents the callers for the tests. If not implemented we will use
#include <libtest/common.h>
+
#include <libtest/gearmand.h>
#include "util/instance.hpp"
#include <cstring>
#include <iostream>
#include <signal.h>
+#include <sstream>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
bool call(const bool success, const std::string &response)
{
_pid= -1;
-
if (success and response.size())
{
_pid= atoi(response.c_str());
}
- if (_pid < 1)
+ if (is_pid_valid(_pid) == false)
{
_pid= -1;
return false;
using namespace libtest;
-class Gearmand : public Server
+class Gearmand : public libtest::Server
{
private:
public:
Gearmand(const std::string& host_arg, in_port_t port_arg) :
- Server(host_arg, port_arg)
- { }
+ libtest::Server(host_arg, port_arg)
+ {
+ set_pid_file();
+ }
pid_t get_pid(bool error_is_ok)
{
bool build(int argc, const char *argv[]);
};
-
-#include <sstream>
-
bool Gearmand::build(int argc, const char *argv[])
{
std::stringstream arg_buffer;
namespace libtest {
-Server *build_gearmand(const char *hostname, in_port_t try_port)
+libtest::Server *build_gearmand(const char *hostname, in_port_t try_port)
{
return new Gearmand(hostname, try_port);
}
#pragma once
+#include <arpa/inet.h>
+
+namespace libtest { class Server; }
+
namespace libtest {
-Server *build_gearmand(const char *hostname, in_port_t try_port);
+libtest::Server *build_gearmand(const char *hostname, in_port_t try_port);
}
# All paths should be given relative to the root
#
-LIBTEST_TMP = ${abs_top_builddir}/tests/var/tmp/
-
-LIBTOOL_COMMAND=$(LIBTOOL) --mode=execute
+LIBTOOL_COMMAND= ${abs_top_builddir}/libtool --mode=execute
VALGRIND_COMMAND= $(LIBTOOL_COMMAND) valgrind --error-exitcode=1 --leak-check=yes --show-reachable=yes --track-fds=yes --malloc-fill=A5 --free-fill=DE
HELGRIND_COMMAND= $(LIBTOOL_COMMAND) valgrind --tool=helgrind --read-var-info=yes --error-exitcode=1
DRD_COMMAND= $(LIBTOOL_COMMAND) valgrind --tool=drd
export DRD_COMMAND
export GDB_COMMAND
+valgrind:
+ @echo make check TESTS_ENVIRONMENT="\"$(VALGRIND_COMMAND)\""
+
+helgrind:
+ @echo make check TESTS_ENVIRONMENT="\"$(HELGRIND_COMMAND)\""
+
+drd:
+ @echo make check TESTS_ENVIRONMENT="\"$(DRD_COMMAND)\""
+
EXTRA_DIST+= libtest/run.gdb
CLEANFILES+= \
- tests/var/log/* \
- tests/var/run/* \
- tests/var/tmp/*
+ tmp_chroot/var/log/* \
+ tmp_chroot/var/run/* \
+ tmp_chroot/var/tmp/*
+
+.PHONY: distclean-libtest-check
+distclean-libtest-check:
+ -rm -rf tmp_chroot
noinst_HEADERS+= \
libtest/blobslap_worker.h \
libtest/gearmand.h \
libtest/get.h \
libtest/killpid.h \
+ libtest/libtool.hpp \
libtest/memcached.h \
libtest/runner.h \
libtest/server.h \
libtest/cmdline.cc \
libtest/framework.cc \
libtest/killpid.cc \
+ libtest/libtool.cc \
libtest/runner.cc \
libtest/server.cc \
libtest/signal.cc \
libtest/test.cc
-libtest_libtest_la_CFLAGS= ${AM_CFLAGS}
-libtest_libtest_la_CFLAGS+= ${NO_CONVERSION}
-libtest_libtest_la_CFLAGS+= $(PTHREAD_CFLAGS)
-libtest_libtest_la_CFLAGS+= -DBUILDING_LIBTEST
-libtest_libtest_la_CPPFLAGS= ${AM_CPPFLAGS}
-libtest_libtest_la_CPPFLAGS+= ${NO_CONVERSION}
-libtest_libtest_la_CPPFLAGS+= $(PTHREAD_LIBS)
-libtest_libtest_la_CPPFLAGS+= -DBUILDING_LIBTEST
libtest_libtest_la_CXXFLAGS= ${AM_CXXFLAGS}
libtest_libtest_la_CXXFLAGS+= ${NO_CONVERSION}
libtest_libtest_la_CXXFLAGS+= -DBUILDING_LIBTEST
libtest_libtest_la_CXXFLAGS+= $(PTHREAD_CFLAGS)
+libtest_libtest_la_CXXFLAGS+= -DLIBTEST_TEMP="\"tmp_chroot\""
libtest_libtest_la_LIBADD=
libtest_libtest_la_LIBADD+= $(PTHREAD_LIBS)
+libtest_libtest_la_DEPENDENCIES= libtest_tmp_dir
-LIBTEST_LDADD= libtest/libtest.la
+# Declare unittest so that we can append to it
+libtest_unittest_CXXFLAGS=
+libtest_unittest_LDADD=
+libtest_unittest_DEPENDENCIES=
-if HAVE_LIBMEMCACHED
+# We are either building in tree, or with
+if BUILDING_LIBMEMCACHED
+libtest_libtest_la_DEPENDENCIES+= libmemcached/libmemcached.la
+libtest_libtest_la_DEPENDENCIES+= libmemcached/libmemcachedutil.la
libtest_libtest_la_LIBADD+= libmemcached/libmemcached.la
libtest_libtest_la_LIBADD+= libmemcached/libmemcachedutil.la
libtest_libtest_la_SOURCES+= libtest/memcached.cc
+libtest_libtest_la_CXXFLAGS+= -DHAVE_LIBMEMCACHED
+
+libtest_unittest_CXXFLAGS+= -DHAVE_LIBMEMCACHED
+libtest_unittest_LDADD+= libmemcached/libmemcached.la
+libtest_unittest_LDADD+= libmemcached/libmemcachedutil.la
+libtest_unittest_DEPENDENCIES+= libmemcached/libmemcached.la
+libtest_unittest_DEPENDENCIES+= libmemcached/libmemcachedutil.la
+else
+if HAVE_LIBMEMCACHED
+libtest_libtest_la_LIBADD+= $(libmemcached_LIBS)
+libtest_libtest_la_SOURCES+= libtest/memcached.cc
+else
+libtest_libtest_la_CXXFLAGS+= -DHAVE_LIBMEMCACHED=0
+libtest_unittest_CXXFLAGS+= -DHAVE_LIBMEMCACHED=0
+endif
endif
+if BUILDING_GEARMAN
+libtest_libtest_la_DEPENDENCIES+= libgearman/libgearman.la
+libtest_libtest_la_LIBADD+= libgearman/libgearman.la
+libtest_libtest_la_SOURCES+= libtest/blobslap_worker.cc
+libtest_libtest_la_SOURCES+= libtest/gearmand.cc
+libtest_libtest_la_SOURCES+= util/instance.cc
+libtest_libtest_la_SOURCES+= util/operation.cc
+libtest_libtest_la_CXXFLAGS+= -DHAVE_LIBGEARMAN
+libtest_libtest_la_CXXFLAGS+= -DGEARMAND_BINARY="\"${abs_top_builddir}/gearmand/gearmand\""
+libtest_libtest_la_CXXFLAGS+= -DGEARMAND_BLOBSLAP_WORKER="\"${abs_top_builddir}/benchmark/blobslap_worker\""
+
+libtest_unittest_CXXFLAGS+= -DHAVE_LIBGEARMAN
+libtest_unittest_LDADD+= libgearman/libgearman.la
+libtest_unittest_DEPENDENCIES+= libgearman/libgearman.la
+else
if HAVE_LIBGEARMAN
-LIBTEST_LDADD+= libgearman/libgearman.la
+libtest_libtest_la_DEPENDENCIES+= libgearman/libgearman.la
+libtest_libtest_la_LIBADD+= $(libgearman_LIBS)
libtest_libtest_la_SOURCES+= libtest/blobslap_worker.cc
libtest_libtest_la_SOURCES+= libtest/gearmand.cc
libtest_libtest_la_SOURCES+= util/instance.cc
libtest_libtest_la_SOURCES+= util/operation.cc
+else
+libtest_libtest_la_CXXFLAGS+= -DGEARMAND_BINARY=0
+libtest_libtest_la_CXXFLAGS+= -DGEARMAND_BLOBSLAP_WORKER=0
+libtest_libtest_la_CXXFLAGS+= -DHAVE_LIBGEARMAN=0
+libtest_unittest_CXXFLAGS+= -DGEARMAND_BINARY=0
+libtest_unittest_CXXFLAGS+= -DHAVE_LIBGEARMAN=0
+endif
endif
-libtest_tmp_dir: tests/var/log tests/var/tmp tests/var/run clearn-var
-
-clearn-var:
- @rm -f tests/var/log/*
- @rm -f tests/var/run/*
- @rm -f tests/var/tmp/*
+libtest_tmp_dir: tmp_chroot/var/log tmp_chroot/var/tmp tmp_chroot/var/run
-tests/var:
- @$(mkdir_p) tests/var
+tmp_chroot:
+ @$(mkdir_p) tmp_chroot
-tests/var/log: tests/var
- @$(mkdir_p) tests/var/log
+tmp_chroot/var: tmp_chroot
+ @$(mkdir_p) tmp_chroot/var
-tests/var/tmp: tests/var
- @$(mkdir_p) tests/var/tmp
+tmp_chroot/var/log: tmp_chroot/var
+ @$(mkdir_p) tmp_chroot/var/log
-tests/var/run: tests/var
- @$(mkdir_p) tests/var/run
+tmp_chroot/var/tmp: tmp_chroot/var
+ @$(mkdir_p) tmp_chroot/var/tmp
-.PHONY+= tests/var
+tmp_chroot/var/run: tmp_chroot/var
+ @$(mkdir_p) tmp_chroot/var/run
-libtest_unittest_CFLAGS=
-libtest_unittest_LDADD= ${LIBTEST_LDADD}
-libtest_unittest_DEPENDENCIES= ${LIBTEST_LDADD} libtest_tmp_dir
+libtest_unittest_CXXFLAGS+= ${AM_CXXFLAGS}
+libtest_unittest_DEPENDENCIES+= libtest/libtest.la libtest_tmp_dir
+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
drd-unittest: libtest/unittest
@$(DRD_COMMAND) libtest/unittest
+libtest_skiptest_LDADD= libtest/libtest.la
+libtest_skiptest_SOURCES= libtest/skiptest.cc
+check_PROGRAMS+= libtest/skiptest
+noinst_PROGRAMS+= libtest/skiptest
+
libtest_wait_SOURCES= libtest/wait.cc
noinst_PROGRAMS+= libtest/wait
-
#include <cstdlib>
#include <cstring>
#include <iostream>
+#include <sstream>
#include <signal.h>
#include <sys/types.h>
#include <sys/types.h>
return ret;
}
-pid_t get_pid_from_file(const std::string &filename)
+#define STRINGIFY(x) #x
+#define TOSTRING(x) STRINGIFY(x)
+#define LIBTEST_AT __FILE__ ":" TOSTRING(__LINE__)
+
+pid_t get_pid_from_file(const std::string &filename, std::stringstream& error_message)
{
pid_t ret= -1;
FILE *fp;
if (filename.empty())
{
- Error << "empty pid file";
+ error_message << LIBTEST_AT << " empty pid file";
return ret;
}
if (ptr)
{
ret= (pid_t)atoi(pid_buffer);
- if (ret <= 0)
+ if (ret < 1)
{
- return ret;
+ error_message << LIBTEST_AT << " Invalid pid was read from file " << filename;
}
}
+ else
+ {
+ error_message << LIBTEST_AT << " File " << filename << " was empty ";
+ }
+
+ return ret;
+ }
+ else
+ {
+ char buffer[1024];
+ char *current_directory= getcwd(buffer, sizeof(buffer));
+ error_message << "Error while opening " << current_directory << "/" << filename << " " << strerror(errno);
}
return ret;
pid_t kill_file(const std::string &filename);
-pid_t get_pid_from_file(const std::string &filename);
+pid_t get_pid_from_file(const std::string &filename, std::stringstream& error_message);
--- /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 <string>
+
+char _libtool[1024]= { 0 };
+
+namespace libtest {
+
+const char *libtool(void)
+{
+ if (_libtool[0])
+ {
+ std::string libtool_buffer;
+ if (getenv("srcdir"))
+ {
+ libtool_buffer+= getenv("srcdir");
+ libtool_buffer+= "/";
+ }
+ else
+ {
+ libtool_buffer+= "./";
+ }
+
+ libtool_buffer+= "libtool";
+ if (access(libtool_buffer.c_str(), R_OK | W_OK | X_OK))
+ {
+ return NULL;
+ }
+
+ libtool_buffer+= " --mode=execute ";
+
+ snprintf(_libtool, sizeof(_libtool), "%s", libtool_buffer.c_str());
+ }
+
+ return _libtool;
+}
+
+}
--- /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 *libtool(void);
+
+}
using namespace libtest;
-class Memcached : public Server
+class Memcached : public libtest::Server
{
+ std::string _username;
+ std::string _password;
+
public:
- Memcached(const std::string& host_arg, const in_port_t port_arg, const bool is_socket_arg) :
- Server(host_arg, port_arg, is_socket_arg)
+ Memcached(const std::string& host_arg, const in_port_t port_arg, const bool is_socket_arg, const std::string& username_arg, const std::string& password_arg) :
+ libtest::Server(host_arg, port_arg, is_socket_arg),
+ _username(username_arg),
+ _password(password_arg)
{ }
+ Memcached(const std::string& host_arg, const in_port_t port_arg, const bool is_socket_arg) :
+ libtest::Server(host_arg, port_arg, is_socket_arg)
+ {
+ set_pid_file();
+ }
+
+ virtual const char *sasl() const
+ {
+ return NULL;
+ }
+
+ const std::string& password() const
+ {
+ return _password;
+ }
+
+ const std::string& username() const
+ {
+ return _username;
+ }
+
pid_t get_pid(bool error_is_ok)
{
// Memcached is slow to start, so we need to do this
memcached_return_t rc;
if (has_socket())
{
- local_pid= libmemcached_util_getpid(socket().c_str(), port(), &rc);
+ 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);
+ }
}
else
{
- local_pid= libmemcached_util_getpid(hostname().c_str(), port(), &rc);
+ 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);
+ }
}
- if (error_is_ok and ((memcached_failed(rc) or local_pid < 1)))
+ if (error_is_ok and ((memcached_failed(rc) or not is_pid_valid(local_pid))))
{
Error << "libmemcached_util_getpid(" << memcached_strerror(NULL, rc) << ") pid: " << local_pid << " for:" << *this;
}
memcached_return_t rc;
bool ret;
+
if (has_socket())
{
- ret= libmemcached_util_ping(socket().c_str(), 0, &rc);
+ 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
{
- ret= libmemcached_util_ping(hostname().c_str(), port(), &rc);
+ 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);
+ }
}
if (memcached_failed(rc) or not ret)
{
- Error << "libmemcached_util_ping(" << memcached_strerror(NULL, rc) << ")";
+ 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);
+ }
}
+
return ret;
}
return false;
}
+ bool broken_socket_cleanup()
+ {
+ return true;
+ }
+
// Memcached's pidfile is broken
bool broken_pid_file()
{
bool build(int argc, const char *argv[]);
};
+class MemcachedSaSL : public Memcached
+{
+public:
+ MemcachedSaSL(const std::string& host_arg, const in_port_t port_arg, const bool is_socket_arg, const std::string& username_arg, const std::string &password_arg) :
+ Memcached(host_arg, port_arg, is_socket_arg, username_arg, password_arg)
+ { }
+
+ const char *name()
+ {
+ return "memcached-sasl";
+ };
+
+ const char *sasl() const
+ {
+ return " -S -B binary ";
+ }
+
+ const char *executable()
+ {
+ return MEMCACHED_SASL_BINARY;
+ }
+
+};
+
#include <sstream>
arg_buffer << " -m 128 ";
arg_buffer << " -M ";
+ if (sasl())
+ {
+ arg_buffer << sasl();
+ }
+
for (int x= 1 ; x < argc ; x++)
{
arg_buffer << " " << argv[x] << " ";
namespace libtest {
-Server *build_memcached(const std::string& hostname, const in_port_t try_port)
+libtest::Server *build_memcached(const std::string& hostname, const in_port_t try_port)
{
return new Memcached(hostname, try_port, false);
}
-Server *build_memcached_socket(const std::string& hostname, const in_port_t try_port)
+libtest::Server *build_memcached_socket(const std::string& socket_file, const in_port_t try_port)
+{
+ return new Memcached(socket_file, try_port, true);
+}
+
+
+libtest::Server *build_memcached_sasl(const std::string& hostname, const in_port_t try_port, const std::string& username, const std::string &password)
+{
+ 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)
{
- return new Memcached(hostname, try_port, true);
+ return new MemcachedSaSL(socket_file, try_port, true, username, password);
}
}
namespace libtest {
-LIBTEST_API
-Server *build_memcached(const std::string& hostname, const in_port_t try_port);
+libtest::Server *build_memcached(const std::string& hostname, const in_port_t try_port);
-LIBTEST_API
-Server *build_memcached_socket(const std::string& socket_file, const in_port_t try_port);
+libtest::Server *build_memcached_socket(const std::string& socket_file, const in_port_t try_port);
+
+libtest::Server *build_memcached_sasl(const std::string& hostname, const in_port_t try_port, const std::string& username, const std::string& 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);
}
#include <libtest/stream.h>
#include <libtest/killpid.h>
-#ifdef HAVE_LIBGEARMAN
-#include <libtest/gearmand.h>
-#include <libtest/blobslap_worker.h>
-#endif
-
-#ifdef HAVE_LIBMEMCACHED
-#include <libtest/memcached.h>
-#endif
-
extern "C" {
static bool exited_successfully(int status)
{
// Try to ping, and kill the server #limit number of times
pid_t current_pid;
- while (--limit and (current_pid= get_pid()) != -1)
+ while (--limit and is_pid_valid(current_pid= get_pid()))
{
if (kill(current_pid))
{
return false;
}
- if (is_helgrind())
+ if (is_helgrind() or is_valgrind())
{
sleep(4);
}
if (pid_file_option() and not pid_file().empty())
{
- Wait wait(pid_file());
+ Wait wait(pid_file(), 8);
if (not wait.successful())
{
- Error << "Unable to open pidfile: " << pid_file();
+ Error << "Unable to open pidfile for: " << _running;
}
}
- int count= is_helgrind() ? 20 : 5;
+ int count= is_helgrind() or is_valgrind() ? 20 : 5;
while (not ping() and --count)
{
nap();
if (count == 0)
{
- Error << "Failed to ping() server once started:" << *this;
+ // If we happen to have a pid file, lets try to kill it
+ if (pid_file_option() and not pid_file().empty())
+ {
+ kill_file(pid_file());
+ }
+ Error << "Failed to ping() server started with:" << _running;
_running.clear();
return false;
}
}
else
{
- snprintf(file_buffer, sizeof(file_buffer), "tests/var/run/%s.socketXXXXXX", name());
+ snprintf(file_buffer, sizeof(file_buffer), "var/run/%s.socketXXXXXX", name());
}
int fd;
}
else
{
- snprintf(file_buffer, sizeof(file_buffer), "tests/var/run/%s.pidXXXXXX", name());
+ snprintf(file_buffer, sizeof(file_buffer), "var/run/%s.pidXXXXXX", name());
}
int fd;
char file_buffer[FILENAME_MAX];
file_buffer[0]= 0;
- snprintf(file_buffer, sizeof(file_buffer), "tests/var/log/%s.logXXXXXX", name());
+ snprintf(file_buffer, sizeof(file_buffer), "var/log/%s.logXXXXXX", name());
int fd;
if ((fd= mkstemp(file_buffer)) == -1)
{
void Server::rebuild_base_command()
{
_base_command.clear();
- if (is_libtool() and getenv("LIBTOOL_COMMAND"))
+ if (is_libtool())
{
- _base_command+= getenv("LIBTOOL_COMMAND");
- _base_command+= " ";
+ _base_command+= libtool();
}
if (is_debug() and getenv("GDB_COMMAND"))
// Update pid_file
if (pid_file_option())
{
- if (not set_pid_file())
+ if (_pid_file.empty() and not set_pid_file())
{
return false;
}
unlink(pid_file().c_str());
}
+ if (broken_socket_cleanup() and has_socket() and not socket().empty())
+ {
+ unlink(socket().c_str());
+ }
+
reset_pid();
return true;
}
}
- Server *server= NULL;
+ libtest::Server *server= NULL;
if (0)
{ }
else if (server_type.compare("gearmand") == 0)
{
-#ifdef GEARMAND_BINARY
- #ifdef HAVE_LIBGEARMAN
- server= build_gearmand("localhost", try_port);
- #else
- Error << "Libgearman was not found";
- #endif
-#else
- Error << "No gearmand binary is available";
-#endif
+ 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)
{
-#ifdef GEARMAND_BINARY
- #ifdef HAVE_LIBGEARMAN
- server= build_blobslap_worker(try_port);
- #else
- Error << "Libgearman was not found";
- #endif
-#else
- Error << "No gearmand binary is available";
-#endif
+ 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)
{
-#ifdef MEMCACHED_BINARY
-#ifdef HAVE_LIBMEMCACHED
- server= build_memcached("localhost", try_port);
-#else
- Error << "Libmemcached was not found";
-#endif
-#else
- Error << "No memcached binary is available";
-#endif
+ 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 << "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)
{
-#ifdef MEMCACHED_BINARY
-#ifdef HAVE_LIBMEMCACHED
- server= build_memcached_socket("localhost", try_port);
-#else
- Error << "Libmemcached was not found";
-#endif
-#else
- Error << "No memcached binary is available";
-#endif
+ 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
{
private:
bool _is_socket;
std::string _socket;
+ std::string _sasl;
std::string _pid_file;
std::string _log_file;
std::string _base_command; // executable command which include libtool, valgrind, gdb, etc
virtual const char *log_file_option()= 0;
virtual bool is_libtool()= 0;
+ virtual bool broken_socket_cleanup()
+ {
+ return false;
+ }
+
virtual const char *socket_file_option() const
{
return NULL;
protected:
void nap();
+ bool set_pid_file();
private:
bool is_helgrind() const;
bool is_valgrind() const;
bool is_debug() const;
bool set_log_file();
- bool set_pid_file();
bool set_socket_file();
void rebuild_base_command();
void reset_pid();
private:
std::string server_list;
bool _socket;
+ bool _sasl;
+ std::string _username;
+ std::string _password;
public:
server_startup_st() :
_socket(false),
+ _sasl(false),
udp(0)
{ }
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;
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 *);
SignalThread::~SignalThread()
{
+ if (not is_shutdown())
+ {
+ set_shutdown(SHUTDOWN_GRACEFUL);
+ }
+
+#if 0
if (pthread_equal(thread, pthread_self()) != 0 and (pthread_kill(thread, 0) == ESRCH) == true)
{
void *retval;
pthread_join(thread, &retval);
}
+#endif
sem_destroy(&lock);
}
--- /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 <config.h>
+
+#include <libtest/test.hpp>
+
+#include <cstdlib>
+#include <unistd.h>
+
+using namespace libtest;
+
+
+collection_st collection[] ={
+ {0, 0, 0, 0}
+};
+
+static void *world_create(server_startup_st&, test_return_t& rc)
+{
+ rc= TEST_SKIPPED;
+
+ return NULL;
+}
+
+void get_world(Framework *world)
+{
+ world->collections= collection;
+ world->_create= world_create;
+}
{
srandom((unsigned int)time(NULL));
+ if (getenv("LIBTEST_QUIET"))
+ {
+ close(STDOUT_FILENO);
+ }
+
+ char buffer[1024];
+ if (getenv("LIBTEST_TMP"))
+ {
+ snprintf(buffer, sizeof(buffer), "%s", getenv("LIBTEST_TMP"));
+ }
+ else
+ {
+ snprintf(buffer, sizeof(buffer), "%s", LIBTEST_TEMP);
+ }
+
+ if (chdir(buffer) == -1)
+ {
+ char getcwd_buffer[1024];
+ char *dir= getcwd(getcwd_buffer, sizeof(getcwd_buffer));
+
+ Error << "Unable to chdir() from " << dir << " to " << buffer << " errno:" << strerror(errno);
+ return EXIT_FAILURE;
+ }
+
+ if (libtest::libtool() == NULL)
+ {
+ Error << "Failed to locate libtool";
+ return EXIT_FAILURE;
+ }
+
world= new Framework();
if (not world)
{
+ Error << "Failed to create Framework()";
return EXIT_FAILURE;
}
case TEST_FATAL:
case TEST_FAILURE:
case TEST_MEMORY_ALLOCATION_FAILURE:
- Error << argv[0] << "create() failed";
+ Error << argv[0] << " failed in Framework::create()";
delete world;
return EXIT_FAILURE;
}
#include <arpa/inet.h>
#include <libtest/visibility.h>
+#include <libtest/version.h>
#include <libtest/error.h>
#include <libtest/server.h>
return TEST_SUCCESS;
}
-#if 0
-static test_return_t pause_test(void *)
+static test_return_t var_exists_test(void *)
{
- (void)getchar();
+ test_compare(0, access("var", R_OK | W_OK | X_OK));
+ return TEST_SUCCESS;
+}
+
+static test_return_t var_tmp_exists_test(void *)
+{
+ test_compare(0, access("var/tmp", R_OK | W_OK | X_OK));
+ return TEST_SUCCESS;
+}
+
+static test_return_t var_run_exists_test(void *)
+{
+ test_compare(0, access("var/run", R_OK | W_OK | X_OK));
+ return TEST_SUCCESS;
+}
+
+static test_return_t var_log_exists_test(void *)
+{
+ test_compare(0, access("var/log", R_OK | W_OK | X_OK));
+ return TEST_SUCCESS;
+}
+
+static test_return_t var_tmp_test(void *)
+{
+ FILE *file= fopen("var/tmp/junk", "w+");
+ char buffer[1024];
+ const char *dir= getcwd(buffer, sizeof(buffer));
+ test_true_got(file, dir);
+ fclose(file);
+ return TEST_SUCCESS;
+}
+
+static test_return_t var_run_test(void *)
+{
+ FILE *file= fopen("var/run/junk", "w+");
+ test_true(file);
+ fclose(file);
+ return TEST_SUCCESS;
+}
+
+static test_return_t var_log_test(void *)
+{
+ FILE *file= fopen("var/log/junk", "w+");
+ test_true(file);
+ fclose(file);
+ return TEST_SUCCESS;
+}
+
+static test_return_t var_tmp_rm_test(void *)
+{
+ test_true(unlink("var/tmp/junk") == 0);
+ return TEST_SUCCESS;
+}
+
+static test_return_t var_run_rm_test(void *)
+{
+ test_true(unlink("var/run/junk") == 0);
return TEST_SUCCESS;
}
-#endif
+static test_return_t var_log_rm_test(void *)
+{
+ test_true(unlink("var/log/junk") == 0);
+ return TEST_SUCCESS;
+}
static test_return_t gearmand_cycle_test(void *object)
{
server_startup_st *servers= (server_startup_st*)object;
test_true(servers);
-#ifndef HAVE_LIBGEARMAN
- return TEST_SKIPPED;
-#endif
+ if (HAVE_LIBGEARMAN)
+ {
+ const char *argv[1]= { "cycle_gearmand" };
+ test_true(server_startup(*servers, "gearmand", 9999, 1, argv));
- const char *argv[1]= { "cycle_gearmand" };
- test_true(server_startup(*servers, "gearmand", 9999, 1, argv));
+ return TEST_SUCCESS;
+ }
- return TEST_SUCCESS;
+ return TEST_SKIPPED;
}
static test_return_t memcached_cycle_test(void *object)
server_startup_st *servers= (server_startup_st*)object;
test_true(servers);
-#if !defined(MEMCACHED_BINARY) || !defined(HAVE_LIBMEMCACHED)
- return TEST_SKIPPED;
-#endif
+ if (MEMCACHED_BINARY and HAVE_LIBMEMCACHED)
+ {
+ const char *argv[1]= { "cycle_memcached" };
+ test_true(server_startup(*servers, "memcached", 9998, 1, argv));
- const char *argv[1]= { "cycle_memcached" };
- test_true(server_startup(*servers, "memcached", 9998, 1, argv));
+ return TEST_SUCCESS;
+ }
- return TEST_SUCCESS;
+ return TEST_SKIPPED;
}
static test_return_t memcached_socket_cycle_test(void *object)
server_startup_st *servers= (server_startup_st*)object;
test_true(servers);
-#if !defined(MEMCACHED_BINARY) || !defined(HAVE_LIBMEMCACHED)
- return TEST_SKIPPED;
-#endif
+ if (MEMCACHED_BINARY and HAVE_LIBMEMCACHED)
+ {
+ const char *argv[1]= { "cycle_memcached" };
+ test_true(servers->start_socket_server("memcached", 9997, 1, argv));
- const char *argv[1]= { "cycle_memcached" };
- test_true(servers->start_socket_server("memcached", 9997, 1, argv));
+ return TEST_SUCCESS;
+ }
- return TEST_SUCCESS;
+ return TEST_SKIPPED;
}
test_st gearmand_tests[] ={
{0, 0, 0}
};
+test_st directories_tests[] ={
+ {"var exists", 0, var_exists_test },
+ {"var/tmp exists", 0, var_tmp_exists_test },
+ {"var/run exists", 0, var_run_exists_test },
+ {"var/log exists", 0, var_log_exists_test },
+ {"var/tmp", 0, var_tmp_test },
+ {"var/run", 0, var_run_test },
+ {"var/log", 0, var_log_test },
+ {"var/tmp rm", 0, var_tmp_rm_test },
+ {"var/run rm", 0, var_run_rm_test },
+ {"var/log rm", 0, var_log_rm_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},
{"gearmand", 0, 0, gearmand_tests},
{"memcached", 0, 0, memcached_tests},
{0, 0, 0, 0}
--- /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
+
+#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
+++ /dev/null
-# ===========================================================================
-# http://autoconf-archive.cryp.to/acx_pthread.html
-# ===========================================================================
-#
-# SYNOPSIS
-#
-# ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
-#
-# DESCRIPTION
-#
-# This macro figures out how to build C programs using POSIX threads. It
-# sets the PTHREAD_LIBS output variable to the threads library and linker
-# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
-# flags that are needed. (The user can also force certain compiler
-# flags/libs to be tested by setting these environment variables.)
-#
-# Also sets PTHREAD_CC to any special C compiler that is needed for
-# multi-threaded programs (defaults to the value of CC otherwise). (This
-# is necessary on AIX to use the special cc_r compiler alias.)
-#
-# NOTE: You are assumed to not only compile your program with these flags,
-# but also link it with them as well. e.g. you should link with
-# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
-#
-# If you are only building threads programs, you may wish to use these
-# variables in your default LIBS, CFLAGS, and CC:
-#
-# LIBS="$PTHREAD_LIBS $LIBS"
-# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-# CC="$PTHREAD_CC"
-#
-# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
-# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
-# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
-#
-# ACTION-IF-FOUND is a list of shell commands to run if a threads library
-# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
-# is not found. If ACTION-IF-FOUND is not specified, the default action
-# will define HAVE_PTHREAD.
-#
-# Please let the authors know if this macro fails on any platform, or if
-# you have any other suggestions or comments. This macro was based on work
-# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
-# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
-# Alejandro Forero Cuervo to the autoconf macro repository. We are also
-# grateful for the helpful feedback of numerous users.
-#
-# LICENSE
-#
-# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation, either version 3 of the License, or (at your
-# option) any later version.
-#
-# This program 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 General
-# Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception, the respective Autoconf Macro's copyright owner
-# gives unlimited permission to copy, distribute and modify the configure
-# scripts that are the output of Autoconf when processing the Macro. You
-# need not follow the terms of the GNU General Public License when using
-# or distributing such scripts, even though portions of the text of the
-# Macro appear in them. The GNU General Public License (GPL) does govern
-# all other use of the material that constitutes the Autoconf Macro.
-#
-# This special exception to the GPL applies to versions of the Autoconf
-# Macro released by the Autoconf Archive. When you make and distribute a
-# modified version of the Autoconf Macro, you may extend this special
-# exception to the GPL to apply to your modified version as well.
-
-AC_DEFUN([ACX_PTHREAD], [
-AC_REQUIRE([AC_CANONICAL_HOST])
-AC_LANG_SAVE
-AC_LANG_C
-acx_pthread_ok=no
-
-# We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
-# It gets checked for in the link test anyway.
-
-# First of all, check if the user has set any of the PTHREAD_LIBS,
-# etcetera environment variables, and if threads linking works using
-# them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- save_LIBS="$LIBS"
- LIBS="$PTHREAD_LIBS $LIBS"
- AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
- AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
- AC_MSG_RESULT($acx_pthread_ok)
- if test x"$acx_pthread_ok" = xno; then
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
- fi
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
-fi
-
-# We must check for the threads library under a number of different
-# names; the ordering is very important because some systems
-# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
-# libraries is broken (non-POSIX).
-
-# Create a list of thread flags to try. Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all, and "pthread-config"
-# which is a program returning the flags for the Pth emulation library.
-
-acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
-
-# The ordering *is* (sometimes) important. Some notes on the
-# individual items follow:
-
-# pthreads: AIX (must check this before -lpthread)
-# none: in case threads are in libc; should be tried before -Kthread and
-# other compiler flags to prevent continual compiler warnings
-# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
-# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-# doesn't hurt to check since this sometimes defines pthreads too;
-# also defines -D_REENTRANT)
-# ... -mt is also the pthreads flag for HP/aCC
-# pthread: Linux, etcetera
-# --thread-safe: KAI C++
-# pthread-config: use pthread-config program (for GNU Pth library)
-
-case "${host_cpu}-${host_os}" in
- *solaris*)
-
- # On Solaris (at least, for some versions), libc contains stubbed
- # (non-functional) versions of the pthreads routines, so link-based
- # tests will erroneously succeed. (We need to link with -pthreads/-mt/
- # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
- # a function called by this macro, so we could check for that, but
- # who knows whether they'll stub that too in a future libc.) So,
- # we'll just look for -pthreads and -lpthread first:
-
- acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
- ;;
-esac
-
-if test x"$acx_pthread_ok" = xno; then
-for flag in $acx_pthread_flags; do
-
- case $flag in
- none)
- AC_MSG_CHECKING([whether pthreads work without any flags])
- ;;
-
- -*)
- AC_MSG_CHECKING([whether pthreads work with $flag])
- PTHREAD_CFLAGS="$flag"
- ;;
-
- pthread-config)
- AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
- if test x"$acx_pthread_config" = xno; then continue; fi
- PTHREAD_CFLAGS="`pthread-config --cflags`"
- PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
- ;;
-
- *)
- AC_MSG_CHECKING([for the pthreads library -l$flag])
- PTHREAD_LIBS="-l$flag"
- ;;
- esac
-
- save_LIBS="$LIBS"
- save_CFLAGS="$CFLAGS"
- LIBS="$PTHREAD_LIBS $LIBS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
- # Check for various functions. We must include pthread.h,
- # since some functions may be macros. (On the Sequent, we
- # need a special flag -Kthread to make this header compile.)
- # We check for pthread_join because it is in -lpthread on IRIX
- # while pthread_create is in libc. We check for pthread_attr_init
- # due to DEC craziness with -lpthreads. We check for
- # pthread_cleanup_push because it is one of the few pthread
- # functions on Solaris that doesn't have a non-functional libc stub.
- # We try pthread_create on general principles.
- AC_TRY_LINK([#include <pthread.h>],
- [pthread_t th; pthread_join(th, 0);
- pthread_attr_init(0); pthread_cleanup_push(0, 0);
- pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
- [acx_pthread_ok=yes])
-
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
-
- AC_MSG_RESULT($acx_pthread_ok)
- if test "x$acx_pthread_ok" = xyes; then
- break;
- fi
-
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
-done
-fi
-
-# Various other checks:
-if test "x$acx_pthread_ok" = xyes; then
- save_LIBS="$LIBS"
- LIBS="$PTHREAD_LIBS $LIBS"
- save_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
- # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
- AC_MSG_CHECKING([for joinable pthread attribute])
- attr_name=unknown
- for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
- AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
- [attr_name=$attr; break])
- done
- AC_MSG_RESULT($attr_name)
- if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
- AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
- [Define to necessary symbol if this constant
- uses a non-standard name on your system.])
- fi
-
- AC_MSG_CHECKING([if more special flags are required for pthreads])
- flag=no
- case "${host_cpu}-${host_os}" in
- *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
- *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
- esac
- AC_MSG_RESULT(${flag})
- if test "x$flag" != xno; then
- PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
- fi
-
- LIBS="$save_LIBS"
- CFLAGS="$save_CFLAGS"
-
- # More AIX lossage: must compile with xlc_r or cc_r
- if test x"$GCC" != xyes; then
- AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
- else
- PTHREAD_CC=$CC
- fi
-else
- PTHREAD_CC="$CC"
-fi
-
-AC_SUBST(PTHREAD_LIBS)
-AC_SUBST(PTHREAD_CFLAGS)
-AC_SUBST(PTHREAD_CC)
-
-# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test x"$acx_pthread_ok" = xyes; then
- ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
- :
-else
- acx_pthread_ok=no
- $2
-fi
-AC_LANG_RESTORE
-])dnl ACX_PTHREAD
--- /dev/null
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+# This macro figures out how to build C programs using POSIX threads. It
+# sets the PTHREAD_LIBS output variable to the threads library and linker
+# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+# flags that are needed. (The user can also force certain compiler
+# flags/libs to be tested by setting these environment variables.)
+#
+# Also sets PTHREAD_CC to any special C compiler that is needed for
+# multi-threaded programs (defaults to the value of CC otherwise). (This
+# is necessary on AIX to use the special cc_r compiler alias.)
+#
+# NOTE: You are assumed to not only compile your program with these flags,
+# but also link it with them as well. e.g. you should link with
+# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+# If you are only building threads programs, you may wish to use these
+# variables in your default LIBS, CFLAGS, and CC:
+#
+# LIBS="$PTHREAD_LIBS $LIBS"
+# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+# CC="$PTHREAD_CC"
+#
+# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+# PTHREAD_CFLAGS.
+#
+# ACTION-IF-FOUND is a list of shell commands to run if a threads library
+# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+# is not found. If ACTION-IF-FOUND is not specified, the default action
+# will define HAVE_PTHREAD.
+#
+# Please let the authors know if this macro fails on any platform, or if
+# you have any other suggestions or comments. This macro was based on work
+# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+# Alejandro Forero Cuervo to the autoconf macro repository. We are also
+# grateful for the helpful feedback of numerous users.
+#
+# Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program 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 General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 16
+
+AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
+AC_DEFUN([AX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_PUSH([C])
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+ AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
+ AC_MSG_RESULT($ax_pthread_ok)
+ if test x"$ax_pthread_ok" = xno; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads too;
+# also defines -D_REENTRANT)
+# ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+ *solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (We need to link with -pthreads/-mt/
+ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
+ # a function called by this macro, so we could check for that, but
+ # who knows whether they'll stub that too in a future libc.) So,
+ # we'll just look for -pthreads and -lpthread first:
+
+ ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
+ ;;
+
+ *-darwin*)
+ ax_pthread_flags="-pthread $ax_pthread_flags"
+ ;;
+esac
+
+if test x"$ax_pthread_ok" = xno; then
+for flag in $ax_pthread_flags; do
+
+ case $flag in
+ none)
+ AC_MSG_CHECKING([whether pthreads work without any flags])
+ ;;
+
+ -*)
+ AC_MSG_CHECKING([whether pthreads work with $flag])
+ PTHREAD_CFLAGS="$flag"
+ ;;
+
+ pthread-config)
+ AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
+ if test x"$ax_pthread_config" = xno; then continue; fi
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ AC_MSG_CHECKING([for the pthreads library -l$flag])
+ PTHREAD_LIBS="-l$flag"
+ ;;
+ esac
+
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+ static void routine(void *a) { a = 0; }
+ static void *start_routine(void *a) { return a; }],
+ [pthread_t th; pthread_attr_t attr;
+ pthread_create(&th, 0, start_routine, 0);
+ pthread_join(th, 0);
+ pthread_attr_init(&attr);
+ pthread_cleanup_push(routine, 0);
+ pthread_cleanup_pop(0) /* ; */])],
+ [ax_pthread_ok=yes],
+ [])
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ AC_MSG_RESULT($ax_pthread_ok)
+ if test "x$ax_pthread_ok" = xyes; then
+ break;
+ fi
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = xyes; then
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+ AC_MSG_CHECKING([for joinable pthread attribute])
+ attr_name=unknown
+ for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+ [int attr = $attr; return attr /* ; */])],
+ [attr_name=$attr; break],
+ [])
+ done
+ AC_MSG_RESULT($attr_name)
+ if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+ AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+ [Define to necessary symbol if this constant
+ uses a non-standard name on your system.])
+ fi
+
+ AC_MSG_CHECKING([if more special flags are required for pthreads])
+ flag=no
+ case "${host_cpu}-${host_os}" in
+ *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+ *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+ esac
+ AC_MSG_RESULT(${flag})
+ if test "x$flag" != xno; then
+ PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+ fi
+
+ AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+ ax_cv_PTHREAD_PRIO_INHERIT, [
+ AC_LINK_IFELSE([
+ AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]])],
+ [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+ [ax_cv_PTHREAD_PRIO_INHERIT=no])
+ ])
+ AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
+ AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ # More AIX lossage: must compile with xlc_r or cc_r
+ if test x"$GCC" != xyes; then
+ AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
+ else
+ PTHREAD_CC=$CC
+ fi
+else
+ PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_pthread_ok" = xyes; then
+ ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+ :
+else
+ ax_pthread_ok=no
+ $2
+fi
+AC_LANG_POP
+])dnl AX_PTHREAD
--- /dev/null
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_with_prog.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_WITH_PROG([VARIABLE],[program],[VALUE-IF-NOT-FOUND],[PATH])
+#
+# DESCRIPTION
+#
+# Locates an installed program binary, placing the result in the precious
+# variable VARIABLE. Accepts a present VARIABLE, then --with-program, and
+# failing that searches for program in the given path (which defaults to
+# the system path). If program is found, VARIABLE is set to the full path
+# of the binary; if it is not found VARIABLE is set to VALUE-IF-NOT-FOUND
+# if provided, unchanged otherwise.
+#
+# A typical example could be the following one:
+#
+# AX_WITH_PROG(PERL,perl)
+#
+# NOTE: This macro is based upon the original AX_WITH_PYTHON macro from
+# Dustin J. Mitchell <dustin@cs.uchicago.edu>.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Francesco Salvestrini <salvestrini@users.sourceforge.net>
+# Copyright (c) 2008 Dustin J. Mitchell <dustin@cs.uchicago.edu>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 16
+
+AC_DEFUN([AX_WITH_PROG],[
+ AC_PREREQ([2.61])
+
+ pushdef([VARIABLE],$1)
+ pushdef([EXECUTABLE],$2)
+ pushdef([VALUE_IF_NOT_FOUND],$3)
+ pushdef([PATH_PROG],$4)
+
+ AC_ARG_VAR(VARIABLE,Absolute path to EXECUTABLE executable)
+
+ AS_IF(test -z "$VARIABLE",[
+ AC_MSG_CHECKING(whether EXECUTABLE executable path has been provided)
+ AC_ARG_WITH(EXECUTABLE,AS_HELP_STRING([--with-EXECUTABLE=[[[PATH]]]],absolute path to EXECUTABLE executable), [
+ AS_IF([test "$withval" != yes && test "$withval" != no],[
+ VARIABLE="$withval"
+ AC_MSG_RESULT($VARIABLE)
+ ],[
+ VARIABLE=""
+ AC_MSG_RESULT([no])
+ AS_IF([test "$withval" != no], [
+ AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[])
+ ])
+ ])
+ ],[
+ AC_MSG_RESULT([no])
+ AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[])
+ ])
+ ])
+
+ popdef([PATH_PROG])
+ popdef([VALUE_IF_NOT_FOUND])
+ popdef([EXECUTABLE])
+ popdef([VARIABLE])
+])
[BUILD_UTILLIB="yes"])
if test "x$BUILD_UTILLIB" = "xyes"; then
- if test x"$acx_pthread_ok" != "xyes"; then
+ if test x"$ax_pthread_ok" != "xyes"; then
AC_MSG_ERROR([Sorry you need POSIX thread library to build libmemcachedutil.])
fi
AC_DEFINE([HAVE_LIBMEMCACHEDUTIL], [1], [Enables libmemcachedutil Support])
+++ /dev/null
-AC_DEFUN([_WITH_LIBGEARMAN],
- [ AC_ARG_ENABLE([libgearman],
- [AS_HELP_STRING([--disable-libgearman],
- [Build with libgearman support @<:@default=on@:>@])],
- [ac_enable_libgearman="$enableval"],
- [ac_enable_libgearman="yes"])
-
- AS_IF([test "x$ac_enable_libgearman" = "xyes"],
- [ PKG_CHECK_MODULES([libgearman], [ libgearman >= 0.24 ],
- [AC_DEFINE([HAVE_LIBGEARMAN], [ 1 ], [Enable libgearman support])],
- [ac_enable_libgearman="no"] )])
-
- AM_CONDITIONAL(HAVE_LIBGEARMAN, test "x${ac_enable_libgearman}" = "xyes")
- ])
-
-AC_DEFUN([WITH_LIBGEARMAN], [ AC_REQUIRE([_WITH_LIBGEARMAN]) ])
-AC_DEFUN([WITH_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$withval" = "xno"],
- [
- ac_cv_with_memcached=memcached
- MEMC_BINARY=memcached
- ],
- [
- AS_IF([test -f "$withval"],
- [
- ac_cv_with_memcached=$withval
- MEMC_BINARY=$withval
- ],
- [
- AC_PATH_PROG([MEMC_BINARY], [$ac_cv_with_memcached], "no")
- AS_IF([test "x$MEMC_BINARY" = "xno"],
- AC_MSG_ERROR(["could not find memcached binary"]))
- ])
- ])
-
- AC_DEFINE_UNQUOTED([MEMCACHED_BINARY], "$MEMC_BINARY",
- [Name of the memcached binary used in make test])
- AC_SUBST(MEMC_BINARY)
-])
+AX_WITH_PROG(MEMCACHED_BINARY,memcached)
+AS_IF([test -f "$ac_cv_path_MEMCACHED_BINARY"],
+ [
+ AC_DEFINE_UNQUOTED([MEMCACHED_BINARY], "$ac_cv_path_MEMCACHED_BINARY", [Name of the memcached binary used in make test])
+ ],
+ [
+ AC_DEFINE([MEMCACHED_BINARY], [0], [Name of the memcached binary used in make test])
+ ])
--- /dev/null
+AX_WITH_PROG(MEMCACHED_SASL_BINARY,memcached_sasl)
+AS_IF([test -f "$ac_cv_path_MEMCACHED_SASL_BINARY"],
+ [
+ AC_DEFINE_UNQUOTED([MEMCACHED_SASL_BINARY], "$ac_cv_path_MEMCACHED_SASL_BINARY", [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])
+ ])
+++ /dev/null
-dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*-
-dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
-dnl
-dnl pandora-build: A pedantic build system
-dnl Copyright (C) 2009 Sun Microsystems, Inc.
-dnl This file is free software; Sun Microsystems
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl From Monty Taylor
-
-dnl --------------------------------------------------------------------
-dnl Check for Google Proto Buffers
-dnl --------------------------------------------------------------------
-
-AC_DEFUN([_PANDORA_SEARCH_LIBPROTOBUF],[
- AC_REQUIRE([PANDORA_HAVE_PTHREAD])
-
- AC_LANG_PUSH([C++])
- save_CXXFLAGS="${CXXFLAGS}"
- CXXFLAGS="${PTHREAD_CFLAGS} ${CXXFLAGS}"
- AC_LIB_HAVE_LINKFLAGS(protobuf,,
- [#include <google/protobuf/descriptor.h>],
- [google::protobuf::FileDescriptor* file;],
- [system])
- CXXFLAGS="${PTHREAD_CFLAGS} ${save_CXXFLAGS}"
- LIBPROTOBUF="${LIBPROTOBUF} ${PTHREAD_LIBS}"
- LTLIBPROTOBUF="${LTLIBPROTOBUF} ${PTHREAD_LIBS}"
- AC_LANG_POP()
-])
-
-AC_DEFUN([PANDORA_HAVE_LIBPROTOBUF],[
- AC_REQUIRE([_PANDORA_SEARCH_LIBPROTOBUF])
-])
-
-AC_DEFUN([PANDORA_REQUIRE_LIBPROTOBUF],[
- AC_REQUIRE([PANDORA_HAVE_LIBPROTOBUF])
- AS_IF([test x$ac_cv_libprotobuf = xno],
- AC_MSG_ERROR([libprotobuf is required for ${PACKAGE}. On Debian this can be found in libprotobuf-dev. On RedHat this can be found in protobuf-devel.]))
-])
-
-AC_DEFUN([PANDORA_PROTOBUF_REQUIRE_VERSION],[
- AC_REQUIRE([_PANDORA_SEARCH_LIBPROTOBUF])
- p_recent_ver=$1
- p_recent_ver_major=`echo $p_recent_ver | cut -f1 -d.`
- p_recent_ver_minor=`echo $p_recent_ver | cut -f2 -d.`
- p_recent_ver_patch=`echo $p_recent_ver | cut -f3 -d.`
- p_recent_ver_hex=`printf "%d%03d%03d" $p_recent_ver_major $p_recent_ver_minor $p_recent_ver_patch`
- AC_LANG_PUSH([C++])
- AC_CACHE_CHECK([for protobuf >= $p_recent_ver],
- [drizzle_cv_protobuf_recent],
- [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include <google/protobuf/descriptor.h>
-#if GOOGLE_PROTOBUF_VERSION < $p_recent_ver_hex
-# error Your version of Protobuf is too old
-#endif
- ]])],
- [drizzle_cv_protobuf_recent=yes],
- [drizzle_cv_protobuf_recent=no])])
- AS_IF([test "$drizzle_cv_protobuf_recent" = "no"],[
- AC_MSG_ERROR([Your version of Google Protocol Buffers is too old. ${PACKAGE} requires at least version $p_recent_ver])
- ])
- AC_LANG_POP()
-])
-
-AC_DEFUN([_PANDORA_SEARCH_PROTOC],[
- AC_REQUIRE([_PANDORA_SEARCH_LIBPROTOBUF])
- AC_PATH_PROG([PROTOC],[protoc],[no],[$LIBPROTOBUF_PREFIX/bin:$PATH])
-])
-
-AC_DEFUN([PANDORA_HAVE_PROTOC],[
- AC_REQUIRE([_PANDORA_SEARCH_PROTOC])
-])
-
-AC_DEFUN([PANDORA_REQUIRE_PROTOC],[
- AC_REQUIRE([PANDORA_HAVE_PROTOC])
- AS_IF([test "x$PROTOC" = "xno"],[
- AC_MSG_ERROR([Couldn't find the protoc compiler. On Debian this can be found in protobuf-compiler. On RedHat this can be found in protobuf-compiler.])
- ])
-])
-
-
+++ /dev/null
-dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*-
-dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
-dnl
-dnl pandora-build: A pedantic build system
-dnl Copyright (C) 2009 Sun Microsystems, Inc.
-dnl This file is free software; Sun Microsystems
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl From Monty Taylor
-
-
-dnl --------------------------------------------------------------------
-dnl Check for libpthread
-dnl --------------------------------------------------------------------
-
-AC_DEFUN([PANDORA_PTHREAD_YIELD],[
- AC_REQUIRE([ACX_PTHREAD])
-
- save_CFLAGS="${CFLAGS}"
- save_CXXFLAGS="${CXXFLAGS}"
- CFLAGS="${PTHREAD_CFLAGS} ${CFLAGS}"
- CXXFLAGS="${PTHREAD_CFLAGS} ${CXXFLAGS}"
- dnl Some OSes like Mac OS X have that as a replacement for pthread_yield()
- AC_CHECK_FUNCS(pthread_yield_np)
- AC_CACHE_CHECK([if pthread_yield takes zero arguments],
- [pandora_cv_pthread_yield_zero_arg],
- [AC_LINK_IFELSE([
- AC_LANG_PROGRAM([[
-#include <pthread.h>
- ]],[[
- pthread_yield();
- ]])],
- [pandora_cv_pthread_yield_zero_arg=yes],
- [pandora_cv_pthread_yield_zero_arg=no])])
- AS_IF([test "$pandora_cv_pthread_yield_zero_arg" = "yes"],[
- AC_DEFINE([HAVE_PTHREAD_YIELD_ZERO_ARG], [1],
- [pthread_yield that doesn't take any arguments])
- ])
-
- AC_CACHE_CHECK([if pthread_yield takes one argument],
- [pandora_cv_pthread_yield_one_arg],
- [AC_LINK_IFELSE([
- AC_LANG_PROGRAM([[
-#include <pthread.h>
- ]],[[
- pthread_yield(0);
- ]])],
- [pandora_cv_pthread_yield_one_arg=yes],
- [pandora_cv_pthread_yield_one_arg=no])])
- AS_IF([test "$pandora_cv_pthread_yield_one_arg" = "yes"],[
- AC_DEFINE([HAVE_PTHREAD_YIELD_ONE_ARG], [1],
- [pthread_yield function with one argument])
- ])
-
- AC_CHECK_FUNCS(pthread_attr_getstacksize pthread_attr_setprio \
- pthread_attr_setschedparam \
- pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \
- pthread_key_delete pthread_rwlock_rdlock pthread_setprio \
- pthread_setprio_np pthread_setschedparam pthread_sigmask \
- pthread_attr_create rwlock_init
-)
-
-
-
-# Check definition of pthread_getspecific
-AC_CACHE_CHECK([args to pthread_getspecific], [pandora_cv_getspecific_args],
- [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#if !defined(_REENTRANT)
-#define _REENTRANT
-#endif
-#ifndef _POSIX_PTHREAD_SEMANTICS
-#define _POSIX_PTHREAD_SEMANTICS
-#endif
-#include <pthread.h>
- ]], [[
-void *pthread_getspecific(pthread_key_t key);
-pthread_getspecific((pthread_key_t) NULL);
- ]])],
- [pandora_cv_getspecific_args=POSIX],
- [pandora_cv_getspecific_args=other])])
- if test "$pandora_cv_getspecific_args" = "other"
- then
- AC_DEFINE([HAVE_NONPOSIX_PTHREAD_GETSPECIFIC], [1],
- [For some non posix threads])
- fi
-
- # Check definition of pthread_mutex_init
- AC_CACHE_CHECK([args to pthread_mutex_init], [pandora_cv_mutex_init_args],
- [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#ifndef _REENTRANT
-#define _REENTRANT
-#endif
-#ifndef _POSIX_PTHREAD_SEMANTICS
-#define _POSIX_PTHREAD_SEMANTICS
-#endif
-#include <pthread.h> ]], [[
- pthread_mutexattr_t attr;
- pthread_mutex_t mp;
- pthread_mutex_init(&mp,&attr); ]])],
- [pandora_cv_mutex_init_args=POSIX],
- [pandora_cv_mutex_init_args=other])])
- if test "$pandora_cv_mutex_init_args" = "other"
- then
- AC_DEFINE([HAVE_NONPOSIX_PTHREAD_MUTEX_INIT], [1],
- [For some non posix threads])
- fi
-#---END:
-
-#---START: Used in for client configure
-# Check definition of readdir_r
-AC_CACHE_CHECK([args to readdir_r], [pandora_cv_readdir_r],
- [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
-#ifndef _REENTRANT
-#define _REENTRANT
-#endif
-#ifndef _POSIX_PTHREAD_SEMANTICS
-#define _POSIX_PTHREAD_SEMANTICS
-#endif
-#include <pthread.h>
-#include <dirent.h>]], [[ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
-readdir_r((DIR *) NULL, (struct dirent *) NULL, (struct dirent **) NULL); ]])],
- [pandora_cv_readdir_r=POSIX],
- [pandora_cv_readdir_r=other])])
-if test "$pandora_cv_readdir_r" = "POSIX"
-then
- AC_DEFINE([HAVE_READDIR_R], [1], [POSIX readdir_r])
-fi
-
-# Check definition of posix sigwait()
-AC_CACHE_CHECK([style of sigwait], [pandora_cv_sigwait],
- [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
-#ifndef _REENTRANT
-#define _REENTRANT
-#endif
-#ifndef _POSIX_PTHREAD_SEMANTICS
-#define _POSIX_PTHREAD_SEMANTICS
-#endif
-#include <pthread.h>
-#include <signal.h>
- ]], [[
-#ifndef _AIX
-sigset_t set;
-int sig;
-sigwait(&set,&sig);
-#endif
- ]])],
- [pandora_cv_sigwait=POSIX],
- [pandora_cv_sigwait=other])])
-if test "$pandora_cv_sigwait" = "POSIX"
-then
- AC_DEFINE([HAVE_SIGWAIT], [1], [POSIX sigwait])
-fi
-
-if test "$pandora_cv_sigwait" != "POSIX"
-then
-unset pandora_cv_sigwait
-# Check definition of posix sigwait()
-AC_CACHE_CHECK([style of sigwait], [pandora_cv_sigwait],
- [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
-#ifndef _REENTRANT
-#define _REENTRANT
-#endif
-#ifndef _POSIX_PTHREAD_SEMANTICS
-#define _POSIX_PTHREAD_SEMANTICS
-#endif
-#include <pthread.h>
-#include <signal.h>
- ]], [[
-sigset_t set;
-int sig;
-sigwait(&set);
- ]])],
- [pandora_cv_sigwait=NONPOSIX],
- [pandora_cv_sigwait=other])])
-if test "$pandora_cv_sigwait" = "NONPOSIX"
-then
- AC_DEFINE([HAVE_NONPOSIX_SIGWAIT], [1], [sigwait with one argument])
-fi
-fi
-#---END:
-
-# Check if pthread_attr_setscope() exists
-AC_CACHE_CHECK([for pthread_attr_setscope], [pandora_cv_pthread_attr_setscope],
- [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
-#ifndef _REENTRANT
-#define _REENTRANT
-#endif
-#ifndef _POSIX_PTHREAD_SEMANTICS
-#define _POSIX_PTHREAD_SEMANTICS
-#endif
-#include <pthread.h>
- ]], [[
-pthread_attr_t thr_attr;
-pthread_attr_setscope(&thr_attr,0);
- ]])],
- [pandora_cv_pthread_attr_setscope=yes],
- [pandora_cv_pthread_attr_setscope=no])])
-if test "$pandora_cv_pthread_attr_setscope" = "yes"
-then
- AC_DEFINE([HAVE_PTHREAD_ATTR_SETSCOPE], [1], [pthread_attr_setscope])
-fi
-
-
-AC_CACHE_CHECK([if pthread_yield takes zero arguments], ac_cv_pthread_yield_zero_arg,
-[AC_TRY_LINK([#define _GNU_SOURCE
-#include <pthread.h>
-#ifdef __cplusplus
-extern "C"
-#endif
-],
-[
- pthread_yield();
-], ac_cv_pthread_yield_zero_arg=yes, ac_cv_pthread_yield_zero_arg=yeso)])
-if test "$ac_cv_pthread_yield_zero_arg" = "yes"
-then
- AC_DEFINE([HAVE_PTHREAD_YIELD_ZERO_ARG], [1],
- [pthread_yield that doesn't take any arguments])
-fi
-AC_CACHE_CHECK([if pthread_yield takes 1 argument], ac_cv_pthread_yield_one_arg,
-[AC_TRY_LINK([#define _GNU_SOURCE
-#include <pthread.h>
-#ifdef __cplusplus
-extern "C"
-#endif
-],
-[
- pthread_yield(0);
-], ac_cv_pthread_yield_one_arg=yes, ac_cv_pthread_yield_one_arg=no)])
-if test "$ac_cv_pthread_yield_one_arg" = "yes"
-then
- AC_DEFINE([HAVE_PTHREAD_YIELD_ONE_ARG], [1],
- [pthread_yield function with one argument])
-fi
-
- CFLAGS="${save_CFLAGS}"
- CXXFLAGS="${save_CXXFLAGS}"
-])
-
-
-AC_DEFUN([_PANDORA_SEARCH_PTHREAD],[
- AC_REQUIRE([ACX_PTHREAD])
- LIBS="${PTHREAD_LIBS} ${LIBS}"
- AM_CFLAGS="${PTHREAD_CFLAGS} ${AM_CFLAGS}"
- AM_CXXFLAGS="${PTHREAD_CFLAGS} ${AM_CXXFLAGS}"
- PANDORA_PTHREAD_YIELD
-])
-
-
-AC_DEFUN([PANDORA_HAVE_PTHREAD],[
- AC_REQUIRE([_PANDORA_SEARCH_PTHREAD])
-])
-
-AC_DEFUN([PANDORA_REQUIRE_PTHREAD],[
- AC_REQUIRE([PANDORA_HAVE_PTHREAD])
- AS_IF([test "x$acx_pthread_ok" != "xyes"],[
- AC_MSG_ERROR(could not find libpthread)])
-])
+++ /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_SASL],[
- AC_REQUIRE([AC_LIB_PREFIX])
-
- dnl --------------------------------------------------------------------
- dnl Check for sasl
- dnl --------------------------------------------------------------------
- AC_ARG_ENABLE([sasl],
- [AS_HELP_STRING([--disable-sasl],
- [Build with sasl support @<:@default=on@:>@])],
- [ac_enable_sasl="$enableval"],
- [ac_enable_sasl="yes"])
-
- AS_IF([test "x$ac_enable_sasl" = "xyes"],
- [
- AC_LIB_HAVE_LINKFLAGS(sasl,,[
- #include <stdlib.h>
- #include <sasl/sasl.h>
- ],[
- sasl_server_init(NULL, NULL);
- ])
-
- AS_IF([test "x${ac_cv_libsasl}" != "xyes" ],
- [
- AC_LIB_HAVE_LINKFLAGS(sasl2,,[
- #include <stdlib.h>
- #include <sasl/sasl.h>
- ],[
- sasl_server_init(NULL, NULL);
- ])
- HAVE_LIBSASL="$HAVE_LIBSASL2"
- LIBSASL="$LIBSASL2"
- LIBSASL_PREFIX="$LIBSASL2_PREFIX"
- LTLIBSASL="$LT_LIBSASL2"
- ])
- ])
-
- AS_IF([test "x${ac_cv_libsasl}" = "xyes" -o "x${ac_cv_libsasl2}" = "xyes"],
- [ac_cv_sasl=yes],
- [ac_cv_sasl=no])
-
- AM_CONDITIONAL(HAVE_LIBSASL, [test "x${ac_cv_libsasl}" = "xyes"])
- AM_CONDITIONAL(HAVE_LIBSASL2, [test "x${ac_cv_libsasl2}" = "xyes"])
- AM_CONDITIONAL(HAVE_SASL, [test "x${ac_cv_sasl}" = "xyes"])
-])
-
-AC_DEFUN([PANDORA_HAVE_SASL],[
- AC_REQUIRE([_PANDORA_SEARCH_SASL])
-])
-
-AC_DEFUN([PANDORA_REQUIRE_SASL],[
- AC_REQUIRE([_PANDORA_SEARCH_SASL])
- AS_IF([test "x${ac_cv_sasl}" = "xno"],
- AC_MSG_ERROR([SASL (libsasl or libsasl2) is required for ${PACKAGE}]))
-])
-
-AC_DEFUN([_PANDORA_SEARCH_LIBSASL],[
- AC_REQUIRE([AC_LIB_PREFIX])
-
- dnl --------------------------------------------------------------------
- dnl Check for libsasl
- dnl --------------------------------------------------------------------
-
- AC_ARG_ENABLE([libsasl],
- [AS_HELP_STRING([--disable-libsasl],
- [Build with libsasl support @<:@default=on@:>@])],
- [ac_enable_libsasl="$enableval"],
- [ac_enable_libsasl="yes"])
-
- AS_IF([test "x$ac_enable_libsasl" = "xyes"],[
- AC_LIB_HAVE_LINKFLAGS(sasl,,[
- #include <stdlib.h>
- #include <sasl/sasl.h>
- ],[
- sasl_server_init(NULL, NULL);
- ])
- ],[
- ac_cv_libsasl="no"
- ])
-
- AM_CONDITIONAL(HAVE_LIBSASL, [test "x${ac_cv_libsasl}" = "xyes"])
-])
-
-AC_DEFUN([PANDORA_HAVE_LIBSASL],[
- AC_REQUIRE([_PANDORA_SEARCH_LIBSASL])
-])
-
-AC_DEFUN([PANDORA_REQUIRE_LIBSASL],[
- AC_REQUIRE([_PANDORA_SEARCH_LIBSASL])
- AS_IF([test "x${ac_cv_libsasl}" = "xno"],
- AC_MSG_ERROR([libsasl is required for ${PACKAGE}]))
-])
-
-AC_DEFUN([_PANDORA_SEARCH_LIBSASL2],[
- AC_REQUIRE([AC_LIB_PREFIX])
-
- dnl --------------------------------------------------------------------
- dnl Check for libsasl2
- dnl --------------------------------------------------------------------
-
- AC_ARG_ENABLE([libsasl2],
- [AS_HELP_STRING([--disable-libsasl2],
- [Build with libsasl2 support @<:@default=on@:>@])],
- [ac_enable_libsasl2="$enableval"],
- [ac_enable_libsasl2="yes"])
-
- AS_IF([test "x$ac_enable_libsasl2" = "xyes"],[
- AC_LIB_HAVE_LINKFLAGS(sasl2,,[
- #include <stdlib.h>
- #include <sasl2/sasl2.h>
- ],[
- sasl2_server_init(NULL, NULL);
- ])
- ],[
- ac_cv_libsasl2="no"
- ])
-
- AM_CONDITIONAL(HAVE_LIBSASL2, [test "x${ac_cv_libsasl2}" = "xyes"])
-])
-
-AC_DEFUN([PANDORA_HAVE_LIBSASL2],[
- AC_REQUIRE([_PANDORA_SEARCH_LIBSASL2])
-])
-
-AC_DEFUN([PANDORA_REQUIRE_LIBSASL2],[
- AC_REQUIRE([_PANDORA_SEARCH_LIBSASL2])
- AS_IF([test "x${ac_cv_libsasl2}" = "xno"],
- AC_MSG_ERROR([libsasl2 is required for ${PACKAGE}]))
-])
includedir=@includedir@
Name: libmemcached
-Description: libmemcached C library.
+URL: http://libmemcachd.org/
+Description: libmemcached C/C++ library.
Version: @VERSION@
-Libs: @LTLIBSASL@ @LTLIBSASL2@ -L${libdir} -lmemcached -lmemcachedutil -pthread
+Libs: -L${libdir} -lmemcached -lmemcachedutil
Cflags: -I${includedir}
};
+#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT +10
#define SERVERS_TO_CREATE 5
#include "libmemcached_world.h"
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached C sasl test app
+ *
+ * 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.
+ *
+ */
+
+/*
+ * @file @brief C dummy test, aka testing C linking, etc
+ */
+
+#include <stdlib.h>
+
+#ifdef HAVE_SASL_SASL_H
+#include <sasl/sasl.h>
+#endif
+
+#include <libmemcached/memcached.h>
+
+int main(void)
+{
+ memcached_st *memc= memcached_create(NULL);
+ memcached_free(memc);
+
+ return EXIT_SUCCESS;
+}
+
};
+#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT +10
#include "tests/libmemcached_world.h"
void get_world(Framework *world)
# Cycle should always run first
tests_cycle_CFLAGS= $(AM_CFLAGS) $(NO_CONVERSION) $(NO_STRICT_ALIASING)
-tests_cycle_CXXFLAGS = $(AM_CXXFLAGS) ${PTHREAD_CFLAGS}
+tests_cycle_CXXFLAGS= $(AM_CXXFLAGS)
+tests_cycle_CXXFLAGS+= ${PTHREAD_CFLAGS}
tests_cycle_SOURCES= tests/cycle.cc
tests_cycle_DEPENDENCIES= $(TESTS_LDADDS)
tests_cycle_LDADD= $(tests_cycle_DEPENDENCIES)
libhashkit/libhashkit.la \
libmemcached/libmemcachedutil.la
tests_testapp_LDADD= \
- $(LIBSASL) \
${PTHREAD_LIBS} \
libmemcached/libmemcached.la \
libmemcached/libmemcachedutil.la \
check_PROGRAMS+= tests/testapp
noinst_PROGRAMS+= tests/testapp
+tests_sasl_CXXFLAGS = $(AM_CXXFLAGS) ${PTHREAD_CFLAGS}
+tests_sasl_CFLAGS= $(AM_CFLAGS) $(NO_CONVERSION) $(NO_STRICT_ALIASING)
+tests_sasl_SOURCES= \
+ tests/basic.cc \
+ tests/debug.cc \
+ tests/deprecated.cc \
+ tests/error_conditions.cc \
+ tests/ketama.cc \
+ tests/sasl.cc \
+ tests/namespace.cc \
+ tests/parser.cc \
+ tests/pool.cc \
+ tests/print.cc \
+ tests/replication.cc \
+ tests/virtual_buckets.cc
+tests_sasl_SOURCES+= clients/generator.cc clients/execute.cc
+tests_sasl_DEPENDENCIES= \
+ libmemcached/libmemcached.la \
+ libtest/libtest.la
+tests_sasl_LDADD= \
+ ${PTHREAD_LIBS} \
+ libmemcached/libmemcached.la \
+ libmemcached/libmemcachedutil.la \
+ libtest/libtest.la \
+ libhashkit/libhashkit.la
+check_PROGRAMS+= tests/sasl
+noinst_PROGRAMS+= tests/sasl
+
tests_testplus_SOURCES= tests/plus.cpp
tests_testplus_CXXFLAGS = $(AM_CXXFLAGS) $(NO_EFF_CXX)
tests_testplus_DEPENDENCIES= $(TESTS_LDADDS)
-tests_testplus_LDADD= $(tests_testplus_DEPENDENCIES) $(LIBSASL)
+tests_testplus_LDADD= $(tests_testplus_DEPENDENCIES)
check_PROGRAMS+= tests/testplus
noinst_PROGRAMS+= tests/testplus
clients/generator.cc \
clients/execute.cc
tests_atomsmasher_DEPENDENCIES= $(TESTS_LDADDS)
-tests_atomsmasher_LDADD= $(tests_atomsmasher_DEPENDENCIES) $(LIBSASL)
+tests_atomsmasher_LDADD= $(tests_atomsmasher_DEPENDENCIES)
noinst_PROGRAMS+= tests/atomsmasher
tests_testudp_CFLAGS= $(AM_CFLAGS) $(NO_CONVERSION) $(NO_STRICT_ALIASING)
tests_testudp_SOURCES= tests/mem_udp.cc
tests_testudp_DEPENDENCIES= $(TESTS_LDADDS)
-tests_testudp_LDADD= $(tests_testudp_DEPENDENCIES) $(LIBSASL)
+tests_testudp_LDADD= $(tests_testudp_DEPENDENCIES)
check_PROGRAMS+= tests/testudp
noinst_PROGRAMS+= tests/testudp
check_PROGRAMS+=tests/c_test
noinst_PROGRAMS+=tests/c_test
+# Test linking with C application/SASL include
+tests_c_sasl_test_SOURCES= tests/c_sasl_test.c
+tests_c_sasl_test_LDADD= libmemcached/libmemcached.la
+tests_c_sasl_test_DEPENDENCIES= libmemcached/libmemcached.la
+check_PROGRAMS+=tests/c_sasl_test
+noinst_PROGRAMS+=tests/c_sasl_test
+
test: check
-check-local: tests/var $(TEST_DOCS)
+check-local: $(TEST_DOCS)
@echo "Tests completed"
-test-x: tests/var test-plus test-memcat test-memcp test-memrm test-memerror test-memdump test-memflush test-memstat
+test-x: test-plus test-memcat test-memcp test-memrm test-memerror test-memdump test-memflush test-memstat
@echo "Tests completed"
test-memcat: clients/memcat clients/memcp
test-mem: tests/var tests/testapp
@tests/testapp
+test-sasl: tests/sasl
+ @tests/sasl
+
+
test-udp: tests/var tests/testudp
@tests/testudp
gdb-mem: tests/testapp
@$(DEBUG_COMMAND) tests/testapp
+gdb-sasl: tests/sasl
+ @$(DEBUG_COMMAND) tests/sasl
+
gdb-atom: tests/atomsmasher
@$(DEBUG_COMMAND) tests/testudp
$(LIBTOOL) --mode=execute valgrind --tool=callgrind --callgrind-out-file=tests/callgrind.out.%p tests/testapp
callgrind_annotate tests/callgrind.out.* --auto=yes > tests/callgrind.out
-test-no-outputdiff: test
-
hudson-valgrind: tests/testapp
$(VALGRIND_COMMAND) --log-file=tests/valgrind.out tests/testapp
};
#define SERVERS_TO_CREATE 5
-#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT +10
static void *world_create(server_startup_st& servers, test_return_t& error)
{
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+ {
+ error= TEST_SKIPPED;
+ return NULL;
+ }
+
in_port_t max_port;
for (uint32_t x= 0; x < SERVERS_TO_CREATE; x++)
{
max_port= port;
const char *argv[1]= { "memcached" };
- if (not server_startup(servers, "memcached", port, 1, argv))
+ if (servers.sasl())
{
- error= TEST_FAILURE;
- return NULL;
+ if (not server_startup(servers, "memcached-sasl", port, 1, argv))
+ {
+ error= TEST_FAILURE;
+ return NULL;
+ }
+ }
+ else
+ {
+ if (not server_startup(servers, "memcached", port, 1, argv))
+ {
+ error= TEST_FAILURE;
+ return NULL;
+ }
}
}
if (servers.socket())
{
- const char *argv[1]= { "memcached" };
- if (not servers.start_socket_server("memcached", max_port +1, 1, argv))
+ if (servers.sasl())
+ {
+ const char *argv[1]= { "memcached" };
+ if (not servers.start_socket_server("memcached-sasl", max_port +1, 1, argv))
+ {
+ error= TEST_FAILURE;
+ return NULL;
+ }
+ }
+ else
{
- error= TEST_FAILURE;
- return NULL;
+ const char *argv[1]= { "memcached" };
+ if (not servers.start_socket_server("memcached", max_port +1, 1, argv))
+ {
+ error= TEST_FAILURE;
+ return NULL;
+ }
}
}
container->parent= memcached(container->construct.option_string().c_str(), container->construct.option_string().size());
test_true(container->parent);
+ if (container->construct.sasl())
+ {
+ if (memcached_failed(memcached_behavior_set(container->parent, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1)))
+ {
+ memcached_free(container->parent);
+ return TEST_FAILURE;
+ }
+
+ if (memcached_failed(memcached_set_sasl_auth_data(container->parent, container->construct.username().c_str(), container->construct.password().c_str())))
+ {
+ memcached_free(container->parent);
+ return TEST_FAILURE;
+ }
+ }
+
for (uint32_t host= 0; host < memcached_server_count(container->parent); ++host)
{
memcached_server_instance_st instance=
static bool world_destroy(void *object)
{
libmemcached_test_container_st *container= (libmemcached_test_container_st *)object;
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
- sasl_done();
+#if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT)
+ {
+ sasl_done();
+ }
#endif
delete container;
memcached_server_instance_st instance=
memcached_server_instance_by_position(memc, 0);
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
- if (memcached_get_sasl_callbacks(memc) != NULL)
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT and memcached_get_sasl_callbacks(memc))
+ {
return TEST_SKIPPED;
-#endif
+ }
+
test_compare(MEMCACHED_SUCCESS, memcached_stat_servername(&memc_stat, NULL,
memcached_server_name(instance),
memcached_server_port(instance)));
return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
}
-static test_return_t pre_sasl(memcached_st *memc)
-{
- memcached_return_t rc= MEMCACHED_FAILURE;
-
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
- const char *server= getenv("LIBMEMCACHED_TEST_SASL_SERVER");
- const char *user= getenv("LIBMEMCACHED_TEST_SASL_USERNAME");
- const char *pass= getenv("LIBMEMCACHED_TEST_SASL_PASSWORD");
-
- if (server and user and pass)
- {
- memcached_server_st *servers= memcached_servers_parse(server);
- test_true(servers);
- memcached_servers_reset(memc);
- test_true(memcached_server_push(memc, servers) == MEMCACHED_SUCCESS);
- memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
- rc= memcached_set_sasl_auth_data(memc, user, pass);
- test_compare(MEMCACHED_SUCCESS, rc);
- }
-#else
- (void)memc;
-#endif
-
- return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
-}
-
static test_return_t pre_replication(memcached_st *memc)
{
test_skip(TEST_SUCCESS, pre_binary(memc));
return TEST_SUCCESS;
}
-/*
- * Test that the sasl authentication works. We cannot use the default
- * pool of servers, because that would require that all servers we want
- * to test supports SASL authentication, and that they use the default
- * creds.
- */
-static test_return_t sasl_auth_test(memcached_st *memc)
-{
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
- test_compare(MEMCACHED_SUCCESS, memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0));
- test_compare(MEMCACHED_SUCCESS, memcached_delete(memc, "foo", 3, 0));
- test_compare(MEMCACHED_SUCCESS, memcached_destroy_sasl_auth_data(memc));
- test_compare(MEMCACHED_FAILURE, memcached_destroy_sasl_auth_data(memc));
- test_compare(MEMCACHED_FAILURE, memcached_destroy_sasl_auth_data(NULL));
- memcached_quit(memc);
-
- test_compare(MEMCACHED_SUCCESS,
- memcached_set_sasl_auth_data(memc,
- getenv("LIBMEMCACHED_TEST_SASL_USERNAME"),
- getenv("LIBMEMCACHED_TEST_SASL_SERVER")));
-
- test_compare(MEMCACHED_AUTH_FAILURE,
- memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0));
- test_compare(MEMCACHED_SUCCESS, memcached_destroy_sasl_auth_data(memc));
-
- memcached_quit(memc);
- return TEST_SUCCESS;
-#else
- (void)memc;
- return TEST_FAILURE;
-#endif
-}
-
/* Clean the server before beginning testing */
test_st tests[] ={
{"util_version", true, (test_callback_fn*)util_version_test },
{0, false, (test_callback_fn*)0}
};
-test_st sasl_auth_tests[]= {
- {"sasl_auth", true, (test_callback_fn*)sasl_auth_test },
- {0, 0, (test_callback_fn*)0}
-};
-
test_st ketama_compatibility[]= {
{"libmemcached", true, (test_callback_fn*)ketama_compatibility_libmemcached },
{"spymemcached", true, (test_callback_fn*)ketama_compatibility_spymemcached },
{"namespace(BINARY)", (test_callback_fn*)set_namespace_and_binary, 0, tests},
{"specific namespace", 0, 0, namespace_tests},
{"specific namespace(BINARY)", (test_callback_fn*)pre_binary, 0, namespace_tests},
- {"sasl_auth", (test_callback_fn*)pre_sasl, 0, sasl_auth_tests },
- {"sasl", (test_callback_fn*)pre_sasl, 0, tests },
{"version_1_2_3", (test_callback_fn*)check_for_1_2_3, 0, version_1_2_3},
{"result", 0, 0, result_tests},
{"async", (test_callback_fn*)pre_nonblock, 0, async_tests},
{0, 0, 0, 0}
};
+#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT +10
+
#include "tests/libmemcached_world.h"
void get_world(Framework *world)
#define SERVERS_TO_CREATE 5
+#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT +10
#include "libmemcached_world.h"
void get_world(Framework *world)
#define SERVERS_TO_CREATE 5
+#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT +10
#include "libmemcached_world.h"
void get_world(Framework *world)
--- /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>
+#include <libtest/test.hpp>
+
+using namespace libtest;
+
+/*
+ Test cases
+*/
+
+#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT +20
+#include <libmemcached/memcached.h>
+
+static test_return_t pre_sasl(memcached_st *)
+{
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
+ {
+ return TEST_SKIPPED;
+ }
+
+ return TEST_SUCCESS;
+}
+
+/*
+ * Test that the sasl authentication works. We cannot use the default
+ * pool of servers, because that would require that all servers we want
+ * to test supports SASL authentication, and that they use the default
+ * creds.
+ */
+static test_return_t sasl_auth_test(memcached_st *memc)
+{
+ if (LIBMEMCACHED_WITH_SASL_SUPPORT)
+ {
+ test_compare(MEMCACHED_SUCCESS, memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0));
+ test_compare(MEMCACHED_SUCCESS, memcached_delete(memc, "foo", 3, 0));
+ test_compare(MEMCACHED_SUCCESS, memcached_destroy_sasl_auth_data(memc));
+ test_compare(MEMCACHED_SUCCESS, memcached_destroy_sasl_auth_data(memc));
+ test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_destroy_sasl_auth_data(NULL));
+ memcached_quit(memc);
+
+ test_compare(MEMCACHED_AUTH_FAILURE,
+ memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0));
+ test_compare(MEMCACHED_SUCCESS, memcached_destroy_sasl_auth_data(memc));
+
+ memcached_quit(memc);
+ return TEST_SUCCESS;
+ }
+
+ return TEST_SKIPPED;
+}
+
+
+test_st sasl_auth_tests[]= {
+ {"sasl_auth", true, (test_callback_fn*)sasl_auth_test },
+ {0, 0, (test_callback_fn*)0}
+};
+
+collection_st collection[] ={
+ {"sasl_auth", (test_callback_fn*)pre_sasl, 0, sasl_auth_tests },
+#if 0
+ {"sasl", (test_callback_fn*)pre_sasl, 0, tests },
+#endif
+ {0, 0, 0, 0}
+};
+
+#include "tests/libmemcached_world.h"
+
+void get_world(Framework *world)
+{
+ 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);
+
+ world->set_sasl("memcached", "memcached");
+}
util/daemon.hpp \
util/instance.hpp \
util/operation.hpp \
+ util/signal.hpp \
util/string.hpp \
util/pidfile.hpp
#include <cstdio>
#include <cstdlib>
#include <cstring>
-#include <errno.h>
+#include <cerrno>
#include <fcntl.h>
#include <iostream>
+#include <sstream>
#include <sys/stat.h>
#include <sys/types.h>
+extern "C" {
+
+ char pid_file[1024 * 4]= { 0 };
+
+ static void remove_pidfile(void)
+ {
+ if (pid_file[0])
+ {
+ if (unlink(pid_file) == -1)
+ {
+ std::cerr << "Could not remove pidfile: " << pid_file << "(" << strerror(errno) << ")" << std::endl;
+ }
+
+ pid_file[0]= 0;
+ }
+ }
+
+}
+
namespace datadifferential {
namespace util {
Pidfile::~Pidfile()
{
- if (not _filename.empty() and (unlink(_filename.c_str()) == -1))
+ if (not _filename.empty())
{
- _error_message+= "Could not remove the pid file: ";
- _error_message+= _filename;
+ if (access(_filename.c_str(), F_OK) == -1)
+ {
+ std::stringstream error_stream;
+ error_stream << "Could not access the pid file: " << _filename << "(" << strerror(errno) << ")";
+ _error_message= error_stream.str();
+ }
+ else if (unlink(_filename.c_str()) == -1)
+ {
+ std::stringstream error_stream;
+ error_stream << "Could not remove the pid file: " << _filename << "(" << strerror(errno) << ")";
+ _error_message= error_stream.str();
+ }
}
+ pid_file[0]= 0;
}
bool Pidfile::create()
{
if (_filename.empty())
+ {
return true;
+ }
+
+ if (access(_filename.c_str(), F_OK) == 0)
+ {
+ if (unlink(_filename.c_str()) == -1)
+ {
+ std::stringstream error_stream;
+ error_stream << "Unable to remove exisiting file:" << _filename << "(" << strerror(errno) << ")";
+ _error_message= error_stream.str();
+
+ return false;
+ }
+ }
int file;
if ((file = open(_filename.c_str(), O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU|S_IRGRP|S_IROTH)) < 0)
{
- _error_message+= "Could not open pid file for writing: ";
- _error_message+= _filename;
+ std::stringstream error_stream;
+ error_stream << "Could not open pid file for writing: " << _filename << "(" << strerror(errno) << ")";
+ _error_message= error_stream.str();
+
return false;
}
char buffer[BUFSIZ];
-
unsigned long temp= static_cast<unsigned long>(getpid());
int length= snprintf(buffer, sizeof(buffer), "%lu\n", temp);
-
if (write(file, buffer, length) != length)
{
- _error_message+= "Could not write pid to file: ";
- _error_message+= _filename;
+ std::stringstream error_stream;
+ error_stream << "Could not write pid to file: " << _filename << "(" << strerror(errno) << ")";
+ _error_message= error_stream.str();
close(file);
return false;
_error_message+= _filename;
return false;
}
+ snprintf(pid_file, sizeof(pid_file), "%s", _filename.c_str());
+ atexit(remove_pidfile);
return true;
}
#pragma once
-
#include <string>
namespace datadifferential {
private:
int _last_errno;
- std::string _filename;
+ const std::string _filename;
std::string _error_message;
};
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * DD Util
+ *
+ * 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 <config.h>
+
+#include <cassert>
+#include <cerrno>
+#include <csignal>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+
+#include <util/signal.hpp>
+
+namespace datadifferential {
+namespace util {
+
+#define MAGIC_MEMORY 123569
+
+bool SignalThread::is_shutdown()
+{
+ bool ret;
+ pthread_mutex_lock(&shutdown_mutex);
+ ret= bool(__shutdown != SHUTDOWN_RUNNING);
+ pthread_mutex_unlock(&shutdown_mutex);
+
+ return ret;
+}
+
+void SignalThread::set_shutdown(shutdown_t arg)
+{
+ pthread_mutex_lock(&shutdown_mutex);
+ __shutdown= arg;
+ pthread_mutex_unlock(&shutdown_mutex);
+
+ if (arg == SHUTDOWN_GRACEFUL)
+ {
+ if (pthread_kill(thread, SIGUSR2) == 0)
+ {
+ void *retval;
+ pthread_join(thread, &retval);
+ }
+ }
+}
+
+shutdown_t SignalThread::get_shutdown()
+{
+ shutdown_t local;
+ pthread_mutex_lock(&shutdown_mutex);
+ local= __shutdown;
+ pthread_mutex_unlock(&shutdown_mutex);
+
+ return local;
+}
+
+void SignalThread::post()
+{
+ sem_post(&lock);
+}
+
+void SignalThread::test()
+{
+ assert(magic_memory == MAGIC_MEMORY);
+ assert(sigismember(&set, SIGABRT));
+ assert(sigismember(&set, SIGINT));
+ assert(sigismember(&set, SIGQUIT));
+ assert(sigismember(&set, SIGTERM));
+ assert(sigismember(&set, SIGUSR2));
+}
+
+SignalThread::~SignalThread()
+{
+ if (not is_shutdown())
+ {
+ set_shutdown(SHUTDOWN_GRACEFUL);
+ }
+
+#if 0
+ if (pthread_equal(thread, pthread_self()) != 0 and (pthread_kill(thread, 0) == ESRCH) == true)
+ {
+ void *retval;
+ pthread_join(thread, &retval);
+ }
+#endif
+ sem_destroy(&lock);
+}
+
+extern "C" {
+
+static void *sig_thread(void *arg)
+{
+ SignalThread *context= (SignalThread*)arg;
+
+ context->test();
+ context->post();
+
+ while (context->get_shutdown() == SHUTDOWN_RUNNING)
+ {
+ int sig;
+
+ if (context->wait(sig) == -1)
+ {
+ std::cerr << "sigwait() returned errno:" << strerror(errno) << std::endl;
+ continue;
+ }
+
+ switch (sig)
+ {
+ case SIGUSR2:
+ break;
+
+ case SIGABRT:
+ case SIGINT:
+ case SIGQUIT:
+ case SIGTERM:
+ if (context->is_shutdown() == false)
+ {
+ context->set_shutdown(SHUTDOWN_FORCED);
+ }
+
+ if (context->exit_on_signal())
+ {
+ exit(EXIT_SUCCESS);
+ }
+
+ break;
+
+ default:
+ std::cerr << "Signal handling thread got unexpected signal " << strsignal(sig) << std::endl;
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+}
+
+SignalThread::SignalThread(bool exit_on_signal_arg) :
+ _exit_on_signal(exit_on_signal_arg),
+ magic_memory(MAGIC_MEMORY),
+ thread(pthread_self())
+{
+ pthread_mutex_init(&shutdown_mutex, NULL);
+ sigemptyset(&set);
+
+ sigaddset(&set, SIGABRT);
+ sigaddset(&set, SIGINT);
+ sigaddset(&set, SIGQUIT);
+ sigaddset(&set, SIGTERM);
+ sigaddset(&set, SIGUSR2);
+
+ sem_init(&lock, 0, 0);
+}
+
+
+bool SignalThread::setup()
+{
+ set_shutdown(SHUTDOWN_RUNNING);
+
+ int error;
+ if ((error= pthread_sigmask(SIG_BLOCK, &set, NULL)) != 0)
+ {
+ std::cerr << "pthread_sigmask() died during pthread_sigmask(" << strerror(error) << ")" << std::endl;
+ return false;
+ }
+
+ if ((error= pthread_create(&thread, NULL, &sig_thread, this)) != 0)
+ {
+ std::cerr << "pthread_create() died during pthread_create(" << strerror(error) << ")" << std::endl;
+ return false;
+ }
+
+ sem_wait(&lock);
+
+ return true;
+}
+
+} /* namespace util */
+} /* namespace datadifferential */
--- /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 <pthread.h>
+#include <semaphore.h>
+
+namespace datadifferential {
+namespace util {
+
+enum shutdown_t {
+ SHUTDOWN_RUNNING,
+ SHUTDOWN_GRACEFUL,
+ SHUTDOWN_FORCED
+};
+
+class SignalThread {
+ bool _exit_on_signal;
+ sigset_t set;
+ sem_t lock;
+ uint64_t magic_memory;
+ volatile shutdown_t __shutdown;
+ pthread_mutex_t shutdown_mutex;
+ pthread_t thread;
+
+public:
+
+ SignalThread(bool exit_on_signal_arg= false);
+
+ void test();
+ void post();
+ bool setup();
+
+ bool exit_on_signal()
+ {
+ return _exit_on_signal;
+ }
+
+ int wait(int& sig)
+ {
+ return sigwait(&set, &sig);
+ }
+
+ ~SignalThread();
+
+ void set_shutdown(shutdown_t arg);
+ bool is_shutdown();
+ shutdown_t get_shutdown();
+};
+
+} /* namespace util */
+} /* namespace datadifferential */