From faae971a1b825275ed3585c9692be3d84a62ce01 Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Tue, 22 Mar 2011 18:41:12 -0700 Subject: [PATCH] Check for failures while configuring client. --- configure.ac | 3 +- libhashkit/function.c | 3 +- libhashkit/strerror.c | 14 +++--- libhashkit/types.h | 2 + libmemcached/behavior.c | 84 +++++++++++++++++++++++++++------- libmemcached/behavior.h | 2 + libmemcached/error.c | 41 ++++++++++++++++- libmemcached/error.h | 6 +++ libmemcached/hash.c | 20 ++++++++ libmemcached/hash.h | 3 ++ libmemcached/options/parser.yy | 80 ++++++++++++++++++++++++++++---- libmemcached/string.c | 9 ++++ libmemcached/string.h | 3 ++ libtest/failed.cc | 75 ++++++++++++++++++++++++++++++ libtest/failed.h | 53 +++++++++++++++++++++ libtest/include.am | 6 ++- libtest/test.c | 7 +++ tests/hashkit_functions.c | 6 +-- tests/mem_functions.c | 4 +- tests/parser.cc | 17 +++++-- 20 files changed, 388 insertions(+), 50 deletions(-) create mode 100644 libtest/failed.cc create mode 100644 libtest/failed.h diff --git a/configure.ac b/configure.ac index 2af6cae1..9349b1f4 100644 --- a/configure.ac +++ b/configure.ac @@ -35,7 +35,7 @@ AC_SUBST(MEMCACHED_PROTOCAL_LIBRARY_VERSION) AC_SUBST(MEMCACHED_LIBRARY_VERSION) -HASHKIT_LIBRARY_VERSION=0:0:0 +HASHKIT_LIBRARY_VERSION=1:0:0 AC_SUBST(HASHKIT_LIBRARY_VERSION) AH_TOP([ @@ -105,7 +105,6 @@ my_saved_libs="$LIBS" LIBS= PANDORA_REQUIRE_PTHREAD LIBS="$my_saved_libs" -PANDORA_CXX_DEMANGLE dnl Specialty checks DETECT_BYTEORDER diff --git a/libhashkit/function.c b/libhashkit/function.c index 2e68b583..a779bb63 100644 --- a/libhashkit/function.c +++ b/libhashkit/function.c @@ -51,9 +51,10 @@ static hashkit_return_t _set_function(struct hashkit_function_st *self, hashkit_ self->function= hashkit_jenkins; break; case HASHKIT_HASH_CUSTOM: + return HASHKIT_INVALID_ARGUMENT; case HASHKIT_HASH_MAX: default: - return HASHKIT_FAILURE; + return HASHKIT_INVALID_HASH; } self->context= NULL; diff --git a/libhashkit/strerror.c b/libhashkit/strerror.c index ac51f996..50532e1d 100644 --- a/libhashkit/strerror.c +++ b/libhashkit/strerror.c @@ -13,15 +13,13 @@ const char *hashkit_strerror(hashkit_st *ptr, hashkit_return_t rc) (void)ptr; switch (rc) { - case HASHKIT_SUCCESS: - return "SUCCESS"; - case HASHKIT_FAILURE: - return "FAILURE"; - case HASHKIT_MEMORY_ALLOCATION_FAILURE: - return "MEMORY ALLOCATION FAILURE"; + case HASHKIT_SUCCESS: return "SUCCESS"; + case HASHKIT_FAILURE: return "FAILURE"; + case HASHKIT_MEMORY_ALLOCATION_FAILURE: return "MEMORY ALLOCATION FAILURE"; + case HASHKIT_INVALID_ARGUMENT: return "INVALID ARGUMENT"; + case HASHKIT_INVALID_HASH: return "INVALID hashkit_hash_algorithm_t"; case HASHKIT_MAXIMUM_RETURN: - return "Gibberish returned!"; default: - return "Gibberish returned!"; + return "INVALID hashkit_return_t"; } } diff --git a/libhashkit/types.h b/libhashkit/types.h index 8d396962..255620b8 100644 --- a/libhashkit/types.h +++ b/libhashkit/types.h @@ -19,6 +19,8 @@ typedef enum { HASHKIT_SUCCESS, HASHKIT_FAILURE, HASHKIT_MEMORY_ALLOCATION_FAILURE, + HASHKIT_INVALID_HASH, + HASHKIT_INVALID_ARGUMENT, HASHKIT_MAXIMUM_RETURN /* Always add new error code before */ } hashkit_return_t; diff --git a/libmemcached/behavior.c b/libmemcached/behavior.c index 055de192..b687eac5 100644 --- a/libmemcached/behavior.c +++ b/libmemcached/behavior.c @@ -129,7 +129,8 @@ memcached_return_t memcached_behavior_set(memcached_st *ptr, break; case MEMCACHED_BEHAVIOR_VERIFY_KEY: if (ptr->flags.binary_protocol) - return MEMCACHED_FAILURE; + return memcached_set_error_string(ptr, MEMCACHED_FAILURE, + memcached_string_with_size("MEMCACHED_BEHAVIOR_VERIFY_KEY if the binary protocol has been enabled.")); ptr->flags.verify_key= set_flag(data); break; case MEMCACHED_BEHAVIOR_SORT_HOSTS: @@ -161,7 +162,8 @@ memcached_return_t memcached_behavior_set(memcached_st *ptr, memcached_quit(ptr); break; case MEMCACHED_BEHAVIOR_USER_DATA: - return MEMCACHED_FAILURE; + return memcached_set_error_string(ptr, MEMCACHED_FAILURE, + memcached_string_with_size("MEMCACHED_BEHAVIOR_USER_DATA deprecated.")); case MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY: ptr->flags.hash_with_prefix_key= set_flag(data); break; @@ -223,17 +225,20 @@ memcached_return_t memcached_behavior_set(memcached_st *ptr, break; case MEM_NOT: default: - return MEMCACHED_NOT_SUPPORTED; + return memcached_set_error_string(ptr, MEMCACHED_NOT_SUPPORTED, + memcached_string_with_size("MEMCACHED_BEHAVIOR_CORK is not supported on this platform.")); } } break; case MEMCACHED_BEHAVIOR_LOAD_FROM_FILE: - return MEMCACHED_FAILURE; + return memcached_set_error_string(ptr, MEMCACHED_INVALID_ARGUMENTS, + memcached_string_with_size("MEMCACHED_BEHAVIOR_LOAD_FROM_FILE can not be set with memcached_behavior_set()")); case MEMCACHED_BEHAVIOR_MAX: default: /* Shouldn't get here */ WATCHPOINT_ASSERT(0); - return MEMCACHED_FAILURE; + return memcached_set_error_string(ptr, MEMCACHED_INVALID_ARGUMENTS, + memcached_string_with_size("Invalid behavior passed to memcached_behavior_set()")); } return MEMCACHED_SUCCESS; @@ -371,7 +376,8 @@ uint64_t memcached_behavior_get(memcached_st *ptr, return (uint64_t) sock_size; } case MEMCACHED_BEHAVIOR_USER_DATA: - return MEMCACHED_FAILURE; + return memcached_set_error_string(ptr, MEMCACHED_FAILURE, + memcached_string_with_size("MEMCACHED_BEHAVIOR_USER_DATA deprecated.")); case MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY: return ptr->flags.hash_with_prefix_key; case MEMCACHED_BEHAVIOR_NOREPLY: @@ -402,13 +408,11 @@ memcached_return_t memcached_behavior_set_distribution(memcached_st *ptr, memcac { ptr->distribution= type; run_distribution(ptr); - } - else - { - return MEMCACHED_FAILURE; + return MEMCACHED_SUCCESS; } - return MEMCACHED_SUCCESS; + return memcached_set_error_string(ptr, MEMCACHED_INVALID_ARGUMENTS, + memcached_string_with_size("Invalid memcached_server_distribution_t")); } @@ -419,10 +423,11 @@ memcached_server_distribution_t memcached_behavior_get_distribution(memcached_st memcached_return_t memcached_behavior_set_key_hash(memcached_st *ptr, memcached_hash_t type) { - hashkit_return_t rc; - rc= hashkit_set_function(&ptr->hashkit, (hashkit_hash_algorithm_t)type); + if (hashkit_set_function(&ptr->hashkit, (hashkit_hash_algorithm_t)type) == HASHKIT_SUCCESS) + return MEMCACHED_SUCCESS; - return rc == HASHKIT_SUCCESS ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; + return memcached_set_error_string(ptr, MEMCACHED_INVALID_ARGUMENTS, + memcached_string_with_size("Invalid memcached_hash_t()")); } memcached_hash_t memcached_behavior_get_key_hash(memcached_st *ptr) @@ -432,13 +437,58 @@ memcached_hash_t memcached_behavior_get_key_hash(memcached_st *ptr) memcached_return_t memcached_behavior_set_distribution_hash(memcached_st *ptr, memcached_hash_t type) { - hashkit_return_t rc; - rc= hashkit_set_function(&ptr->distribution_hashkit, (hashkit_hash_algorithm_t)type); + if (hashkit_set_function(&ptr->distribution_hashkit, (hashkit_hash_algorithm_t)type) == HASHKIT_SUCCESS) + return MEMCACHED_SUCCESS; - return rc == HASHKIT_SUCCESS ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE; + return memcached_set_error_string(ptr, MEMCACHED_INVALID_ARGUMENTS, + memcached_string_with_size("Invalid memcached_hash_t()")); } memcached_hash_t memcached_behavior_get_distribution_hash(memcached_st *ptr) { return (memcached_hash_t)hashkit_get_function(&ptr->distribution_hashkit); } + +const char *libmemcached_string_behavior(const memcached_behavior_t flag) +{ + switch (flag) + { + case MEMCACHED_BEHAVIOR_NO_BLOCK: return "MEMCACHED_BEHAVIOR_NO_BLOCK"; + case MEMCACHED_BEHAVIOR_TCP_NODELAY: return "MEMCACHED_BEHAVIOR_TCP_NODELAY"; + case MEMCACHED_BEHAVIOR_HASH: return "MEMCACHED_BEHAVIOR_HASH"; + case MEMCACHED_BEHAVIOR_KETAMA: return "MEMCACHED_BEHAVIOR_KETAMA"; + case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE: return "MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE"; + case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE: return "MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE"; + case MEMCACHED_BEHAVIOR_CACHE_LOOKUPS: return "MEMCACHED_BEHAVIOR_CACHE_LOOKUPS"; + case MEMCACHED_BEHAVIOR_SUPPORT_CAS: return "MEMCACHED_BEHAVIOR_SUPPORT_CAS"; + case MEMCACHED_BEHAVIOR_POLL_TIMEOUT: return "MEMCACHED_BEHAVIOR_POLL_TIMEOUT"; + case MEMCACHED_BEHAVIOR_DISTRIBUTION: return "MEMCACHED_BEHAVIOR_DISTRIBUTION"; + case MEMCACHED_BEHAVIOR_BUFFER_REQUESTS: return "MEMCACHED_BEHAVIOR_BUFFER_REQUESTS"; + case MEMCACHED_BEHAVIOR_USER_DATA: return "MEMCACHED_BEHAVIOR_USER_DATA"; + case MEMCACHED_BEHAVIOR_SORT_HOSTS: return "MEMCACHED_BEHAVIOR_SORT_HOSTS"; + case MEMCACHED_BEHAVIOR_VERIFY_KEY: return "MEMCACHED_BEHAVIOR_VERIFY_KEY"; + case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT: return "MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT"; + case MEMCACHED_BEHAVIOR_RETRY_TIMEOUT: return "MEMCACHED_BEHAVIOR_RETRY_TIMEOUT"; + case MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED: return "MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED"; + case MEMCACHED_BEHAVIOR_KETAMA_HASH: return "MEMCACHED_BEHAVIOR_KETAMA_HASH"; + case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL: return "MEMCACHED_BEHAVIOR_BINARY_PROTOCOL"; + case MEMCACHED_BEHAVIOR_SND_TIMEOUT: return "MEMCACHED_BEHAVIOR_SND_TIMEOUT"; + case MEMCACHED_BEHAVIOR_RCV_TIMEOUT: return "MEMCACHED_BEHAVIOR_RCV_TIMEOUT"; + case MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT: return "MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT"; + case MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK: return "MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK"; + case MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK: return "MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK"; + case MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH: return "MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH"; + case MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY: return "MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY"; + case MEMCACHED_BEHAVIOR_NOREPLY: return "MEMCACHED_BEHAVIOR_NOREPLY"; + case MEMCACHED_BEHAVIOR_USE_UDP: return "MEMCACHED_BEHAVIOR_USE_UDP"; + case MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS: return "MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS"; + case MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS: return "MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS"; + case MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ: return "MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ"; + case MEMCACHED_BEHAVIOR_CORK: return "MEMCACHED_BEHAVIOR_CORK"; + case MEMCACHED_BEHAVIOR_TCP_KEEPALIVE: return "MEMCACHED_BEHAVIOR_TCP_KEEPALIVE"; + case MEMCACHED_BEHAVIOR_TCP_KEEPIDLE: return "MEMCACHED_BEHAVIOR_TCP_KEEPIDLE"; + case MEMCACHED_BEHAVIOR_LOAD_FROM_FILE: return "MEMCACHED_BEHAVIOR_LOAD_FROM_FILE"; + default: + case MEMCACHED_BEHAVIOR_MAX: return "INVALID BEHAVIOR"; + } +} diff --git a/libmemcached/behavior.h b/libmemcached/behavior.h index 39a430d7..c5f855ee 100644 --- a/libmemcached/behavior.h +++ b/libmemcached/behavior.h @@ -43,6 +43,8 @@ memcached_hash_t memcached_behavior_get_distribution_hash(memcached_st *ptr); LIBMEMCACHED_LOCAL bool _is_auto_eject_host(const memcached_st *ptr); +LIBMEMCACHED_LOCAL + const char *libmemcached_string_behavior(const memcached_behavior_t flag); #ifdef __cplusplus } diff --git a/libmemcached/error.c b/libmemcached/error.c index 206e1b41..81f6504d 100644 --- a/libmemcached/error.c +++ b/libmemcached/error.c @@ -64,8 +64,12 @@ static memcached_error_st *_set(memcached_st *memc, memcached_string_t *str) { error->size= str->size; memcpy(error->c_str, str->c_str, str->size); + error->c_str[str->size]= 0; + } + else + { + error->size= 0; } - error->c_str[(str ? str->size :0)]= 0; error->next= memc->error_messages; memc->error_messages= error; @@ -73,6 +77,14 @@ static memcached_error_st *_set(memcached_st *memc, memcached_string_t *str) return error; } +memcached_return_t memcached_set_error_string(memcached_st *memc, memcached_return_t rc, const char *str, size_t length) +{ + memcached_string_t tmp; + tmp.c_str= str; + tmp.size= length; + return memcached_set_error(memc, rc, &tmp); +} + memcached_return_t memcached_set_error(memcached_st *memc, memcached_return_t rc, memcached_string_t *str) { if (rc == MEMCACHED_SUCCESS) @@ -102,6 +114,31 @@ memcached_return_t memcached_set_errno(memcached_st *memc, int local_errno, memc return error->rc; } +static void _error_print(const memcached_error_st *error) +{ + if (! error) + return; + + if (! error->size) + { + fprintf(stderr, "%s\n", memcached_strerror(NULL, error->rc) ); + } + else + { + fprintf(stderr, "%s %s\n", memcached_strerror(NULL, error->rc), error->c_str); + } + + _error_print(error->next); +} + +void memcached_error_print(const memcached_st *self) +{ + if (! self) + return; + + _error_print(self->error_messages); +} + static void _error_free(memcached_error_st *error) { if (! error) @@ -135,7 +172,7 @@ const char *memcached_last_error_message(memcached_st *memc) if (! memc->error_messages) return memcached_strerror(memc, MEMCACHED_SUCCESS); - if (! memc->error_messages->c_str) + if (! memc->error_messages->size) { return memcached_strerror(memc, memc->error_messages->rc); } diff --git a/libmemcached/error.h b/libmemcached/error.h index 28038d09..d9a08dd7 100644 --- a/libmemcached/error.h +++ b/libmemcached/error.h @@ -44,6 +44,9 @@ extern "C" { LIBMEMCACHED_LOCAL memcached_return_t memcached_set_error(memcached_st *memc, memcached_return_t rc, memcached_string_t *str); +LIBMEMCACHED_LOCAL + memcached_return_t memcached_set_error_string(memcached_st *memc, memcached_return_t rc, const char *str, size_t length); + LIBMEMCACHED_LOCAL memcached_return_t memcached_set_errno(memcached_st *memc, int local_errno, memcached_string_t *str); @@ -53,6 +56,9 @@ LIBMEMCACHED_LOCAL LIBMEMCACHED_API const char *memcached_last_error_message(memcached_st *memc); +LIBMEMCACHED_API + void memcached_error_print(const memcached_st *self); + LIBMEMCACHED_API memcached_return_t memcached_last_error(memcached_st *memc); diff --git a/libmemcached/hash.c b/libmemcached/hash.c index a9c1f8ed..d1515f69 100644 --- a/libmemcached/hash.c +++ b/libmemcached/hash.c @@ -136,3 +136,23 @@ memcached_return_t memcached_set_hashkit(memcached_st *self, hashkit_st *hashk) return MEMCACHED_SUCCESS; } + +const char * libmemcached_string_hash(memcached_hash_t type) +{ + switch (type) + { + case MEMCACHED_HASH_DEFAULT: return "MEMCACHED_HASH_DEFAULT"; + case MEMCACHED_HASH_MD5: return "MEMCACHED_HASH_MD5"; + case MEMCACHED_HASH_CRC: return "MEMCACHED_HASH_CRC"; + case MEMCACHED_HASH_FNV1_64: return "MEMCACHED_HASH_FNV1_64"; + case MEMCACHED_HASH_FNV1A_64: return "MEMCACHED_HASH_FNV1A_64"; + case MEMCACHED_HASH_FNV1_32: return "MEMCACHED_HASH_FNV1_32"; + case MEMCACHED_HASH_FNV1A_32: return "MEMCACHED_HASH_FNV1A_32"; + case MEMCACHED_HASH_HSIEH: return "MEMCACHED_HASH_HSIEH"; + case MEMCACHED_HASH_MURMUR: return "MEMCACHED_HASH_MURMUR"; + case MEMCACHED_HASH_JENKINS: return "MEMCACHED_HASH_JENKINS"; + case MEMCACHED_HASH_CUSTOM: return "MEMCACHED_HASH_CUSTOM"; + default: + case MEMCACHED_HASH_MAX: return "INVALID memcached_hash_t"; + } +} diff --git a/libmemcached/hash.h b/libmemcached/hash.h index 0e664266..1480c3b9 100644 --- a/libmemcached/hash.h +++ b/libmemcached/hash.h @@ -35,6 +35,9 @@ uint32_t memcached_generate_hash_with_redistribution(memcached_st *ptr, const ch LIBMEMCACHED_API void memcached_autoeject(memcached_st *ptr); +LIBMEMCACHED_API + const char * libmemcached_string_hash(memcached_hash_t type); + #ifdef __cplusplus } #endif diff --git a/libmemcached/options/parser.yy b/libmemcached/options/parser.yy index 00ad0631..20f17c75 100644 --- a/libmemcached/options/parser.yy +++ b/libmemcached/options/parser.yy @@ -20,8 +20,12 @@ %{ +#include + #include #include +#include +#include #include #include @@ -156,7 +160,8 @@ statement: expression: SERVER '=' server { - (void) memcached_server_add_parsed(parser->memc, $3.c_str, $3.length, $3.port, 0); + if (memcached_server_add_parsed(parser->memc, $3.c_str, $3.length, $3.port, 0) != MEMCACHED_SUCCESS) + YYERROR; } | SERVERS '=' server_list { @@ -171,27 +176,68 @@ expression: behaviors: PREFIX_KEY '=' string { - memcached_callback_set(parser->memc, MEMCACHED_CALLBACK_PREFIX_KEY, std::string($3.c_str, $3.length).c_str()); + memcached_return_t rc; + if ((rc= memcached_callback_set(parser->memc, MEMCACHED_CALLBACK_PREFIX_KEY, std::string($3.c_str, $3.length).c_str())) != MEMCACHED_SUCCESS) + { + std::string error_message("--PREFIX-KEY"); + error_message.append($3.c_str, $3.length); + memcached_string_t tmp= memcached_string_make(error_message.c_str(), error_message.size()); + memcached_set_error(parser->memc, rc, &tmp); + YYERROR; + } } | DISTRIBUTION '=' distribution { - memcached_behavior_set(parser->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $3); + memcached_return_t rc; + if ((rc= memcached_behavior_set(parser->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $3)) != MEMCACHED_SUCCESS) + { + memcached_string_t tmp= memcached_string_make(memcached_string_with_size("--DISTRIBUTION")); + memcached_set_error(parser->memc, rc, &tmp); + YYERROR; + } } | HASH '=' hash { - memcached_behavior_set(parser->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $3); + memcached_return_t rc; + if ((rc= memcached_behavior_set(parser->memc, MEMCACHED_BEHAVIOR_HASH, $3)) != MEMCACHED_SUCCESS) + { + std::string buffer; + buffer+= "--HASH="; + buffer+= libmemcached_string_hash($3); + memcached_string_t tmp= memcached_string_make(buffer.c_str(), buffer.size()); + memcached_set_error(parser->memc, rc, &tmp); + YYERROR; + } } | KETAMA_HASH '=' hash { - memcached_behavior_set(parser->memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, $3); + memcached_return_t rc; + if ((rc= memcached_behavior_set(parser->memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, $3)) != MEMCACHED_SUCCESS) + { + memcached_string_t tmp= memcached_string_make(memcached_string_with_size("--KETAMA-HASH")); + memcached_set_error(parser->memc, rc, &tmp); + YYERROR; + } } | behavior_number '=' NUMBER { - memcached_behavior_set(parser->memc, $1, $3); + memcached_return_t rc; + if ((rc= memcached_behavior_set(parser->memc, $1, $3)) != MEMCACHED_SUCCESS) + { + memcached_string_t tmp= memcached_string_make(libmemcached_string_behavior($1), strlen(libmemcached_string_behavior($1))); + memcached_set_error(parser->memc, rc, &tmp); + YYERROR; + } } | behavior_boolean { - memcached_behavior_set(parser->memc, $1, true); + memcached_return_t rc; + if ((rc= memcached_behavior_set(parser->memc, $1, true)) != MEMCACHED_SUCCESS) + { + memcached_string_t tmp= memcached_string_make(libmemcached_string_behavior($1), strlen(libmemcached_string_behavior($1))); + memcached_set_error(parser->memc, rc, &tmp); + YYERROR; + } } | USER_DATA { @@ -323,11 +369,27 @@ behavior_boolean: server_list: server { - (void) memcached_server_add_parsed(parser->memc, $1.c_str, $1.length, $1.port, 0); + memcached_return_t rc; + if ((rc= memcached_server_add_parsed(parser->memc, $1.c_str, $1.length, $1.port, 0)) != MEMCACHED_SUCCESS) + { + std::stringstream ss; + ss << "--SERVER=" << $1; + memcached_string_t tmp= memcached_string_make(ss.str().c_str(), ss.str().length()); + memcached_set_error(parser->memc, rc, &tmp); + YYERROR; + } } | server_list ',' server { - (void) memcached_server_add_parsed(parser->memc, $3.c_str, $3.length, $3.port, 0); + memcached_return_t rc; + if ((rc= memcached_server_add_parsed(parser->memc, $3.c_str, $3.length, $3.port, 0)) != MEMCACHED_SUCCESS) + { + std::stringstream ss; + ss << "--SERVERS=" << $3; + memcached_string_t tmp= memcached_string_make(ss.str().c_str(), ss.str().length()); + memcached_set_error(parser->memc, rc, &tmp); + YYERROR; + } } ; diff --git a/libmemcached/string.c b/libmemcached/string.c index 34597067..10a29581 100644 --- a/libmemcached/string.c +++ b/libmemcached/string.c @@ -212,3 +212,12 @@ void memcached_string_set_length(memcached_string_st *self, size_t length) { self->end= self->string + length; } + +memcached_string_t memcached_string_make(const char *str, size_t length) +{ + memcached_string_t tmp; + tmp.c_str= str; + tmp.size= length; + + return tmp; +} diff --git a/libmemcached/string.h b/libmemcached/string.h index f6a13bb0..5dd7d8dd 100644 --- a/libmemcached/string.h +++ b/libmemcached/string.h @@ -80,6 +80,9 @@ char *memcached_string_value_mutable(const memcached_string_st *self); LIBMEMCACHED_LOCAL void memcached_string_set_length(memcached_string_st *self, size_t length); +LIBMEMCACHED_LOCAL +memcached_string_t memcached_string_make(const char *str, size_t length); + #ifdef __cplusplus } #endif diff --git a/libtest/failed.cc b/libtest/failed.cc new file mode 100644 index 00000000..df022467 --- /dev/null +++ b/libtest/failed.cc @@ -0,0 +1,75 @@ +/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: + * + * uTest Framework + * + * Copyright (C) 2011 Data Differential, http://datadifferential.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * The names of its contributors may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include + +#include +#include +#include + +struct failed_test_names_st +{ + failed_test_names_st(const char *collection_arg, const char *test_arg) : + collection(collection_arg), + test(test_arg) + { + } + + std::string collection; + std::string test; +}; + +typedef std::vector Failures; + +static Failures failures; + +void push_failed_test(const char *collection, const char *test) +{ + failures.push_back(failed_test_names_st(collection, test)); +} + +void print_failed_test(void) +{ + for (Failures::iterator iter= failures.begin(); iter != failures.end(); iter++) + { + std::cerr << "\t" << (*iter).collection << " " << (*iter).test << std::endl; + } + std::cerr << std::endl; +} + diff --git a/libtest/failed.h b/libtest/failed.h new file mode 100644 index 00000000..16d1aecc --- /dev/null +++ b/libtest/failed.h @@ -0,0 +1,53 @@ +/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: + * + * uTest Framework + * + * Copyright (C) 2011 Data Differential, http://datadifferential.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * The names of its contributors may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +LIBTEST_INTERNAL_API + void push_failed_test(const char *collection, const char *test); + +LIBTEST_INTERNAL_API + void print_failed_test(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtest/include.am b/libtest/include.am index e6012ddc..f14d9435 100644 --- a/libtest/include.am +++ b/libtest/include.am @@ -9,6 +9,7 @@ # All paths should be given relative to the root noinst_HEADERS+= \ + libtest/failed.h \ libtest/server.h \ libtest/test.h \ libtest/visibility.h @@ -17,5 +18,8 @@ noinst_LTLIBRARIES+= libtest/libserver.la libtest_libserver_la_SOURCES= libtest/server.c noinst_LTLIBRARIES+= libtest/libtest.la -libtest_libtest_la_SOURCES= libtest/test.c +libtest_libtest_la_SOURCES=\ + libtest/test.c +libtest_libtest_la_CFLAGS= ${AM_CFLAGS} ${NO_CONVERSION} +libtest_libtest_la_CPPFLAGS= ${AM_CPPFLAGS} diff --git a/libtest/test.c b/libtest/test.c index 3d11d208..da989b17 100644 --- a/libtest/test.c +++ b/libtest/test.c @@ -27,6 +27,7 @@ #include #include +#include static void world_stats_print(world_stats_st *stats) { @@ -298,6 +299,9 @@ skip_pre: stats.success++; break; case TEST_FAILURE: +#if 0 + push_failed_test(next->name, run->name); +#endif stats.failed++; failed= true; break; @@ -343,6 +347,9 @@ cleanup: if (stats.collection_failed || stats.collection_skipped) { fprintf(stderr, "Some test failures and/or skipped test occurred.\n\n"); +#if 0 + print_failed_test(); +#endif } else { diff --git a/tests/hashkit_functions.c b/tests/hashkit_functions.c index 0f2c42a9..23feb9e5 100644 --- a/tests/hashkit_functions.c +++ b/tests/hashkit_functions.c @@ -345,10 +345,10 @@ static test_return_t hashkit_set_function_test(hashkit_st *hashk) continue; #endif - if (rc == HASHKIT_FAILURE && algo == HASHKIT_HASH_CUSTOM) + if (rc == HASHKIT_INVALID_ARGUMENT && algo == HASHKIT_HASH_CUSTOM) continue; - test_true(rc == HASHKIT_SUCCESS); + test_true_got(rc == HASHKIT_SUCCESS, hashkit_strerror(NULL, rc)); switch (algo) { @@ -448,7 +448,7 @@ static test_return_t hashkit_set_distribution_function_test(hashkit_st *hashk) if (rc == HASHKIT_FAILURE && algo == HASHKIT_HASH_HSIEH) continue; - if (rc == HASHKIT_FAILURE && algo == HASHKIT_HASH_CUSTOM) + if (rc == HASHKIT_INVALID_ARGUMENT && algo == HASHKIT_HASH_CUSTOM) continue; test_true(rc == HASHKIT_SUCCESS); diff --git a/tests/mem_functions.c b/tests/mem_functions.c index b2e8be2b..07587fdc 100644 --- a/tests/mem_functions.c +++ b/tests/mem_functions.c @@ -4594,7 +4594,7 @@ static test_return_t hash_sanity_test (memcached_st *memc) static test_return_t hsieh_avaibility_test (memcached_st *memc) { - memcached_return_t expected_rc= MEMCACHED_FAILURE; + memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS; #ifdef HAVE_HSIEH_HASH expected_rc= MEMCACHED_SUCCESS; #endif @@ -4607,7 +4607,7 @@ static test_return_t hsieh_avaibility_test (memcached_st *memc) static test_return_t murmur_avaibility_test (memcached_st *memc) { - memcached_return_t expected_rc= MEMCACHED_FAILURE; + memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS; #ifdef HAVE_MURMUR_HASH expected_rc= MEMCACHED_SUCCESS; #endif diff --git a/tests/parser.cc b/tests/parser.cc index b69e4486..37b9daad 100644 --- a/tests/parser.cc +++ b/tests/parser.cc @@ -37,6 +37,8 @@ #include +#include + #include #include "tests/parser.h" @@ -194,7 +196,9 @@ scanner_variable_t test_boolean_options[]= { { ARRAY, make_scanner_string("--BINARY_PROTOCOL"), scanner_string_null, NULL }, { ARRAY, make_scanner_string("--BUFFER_REQUESTS"), scanner_string_null, NULL }, { ARRAY, make_scanner_string("--CACHE_LOOKUPS"), scanner_string_null, __check_CACHE_LOOKUPS }, +#if 0 // Not all platforms support { ARRAY, make_scanner_string("--CORK"), scanner_string_null, NULL }, +#endif { ARRAY, make_scanner_string("--HASH_WITH_PREFIX_KEY"), scanner_string_null, NULL }, { ARRAY, make_scanner_string("--KETAMA"), scanner_string_null, NULL }, { ARRAY, make_scanner_string("--KETAMA_WEIGHTED"), scanner_string_null, NULL }, @@ -225,14 +229,14 @@ scanner_variable_t distribution_strings[]= { }; scanner_variable_t hash_strings[]= { - { ARRAY, make_scanner_string("--HASH=MD5"), scanner_string_null, NULL }, { ARRAY, make_scanner_string("--HASH=CRC"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--HASH=FNV1_64"), scanner_string_null, NULL }, + { ARRAY, make_scanner_string("--HASH=FNV1A_32"), scanner_string_null, NULL }, { ARRAY, make_scanner_string("--HASH=FNV1A_64"), scanner_string_null, NULL }, { ARRAY, make_scanner_string("--HASH=FNV1_32"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--HASH=FNV1A_32"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--HASH=MURMUR"), scanner_string_null, NULL }, + { ARRAY, make_scanner_string("--HASH=FNV1_64"), scanner_string_null, NULL }, { ARRAY, make_scanner_string("--HASH=JENKINS"), scanner_string_null, NULL }, + { ARRAY, make_scanner_string("--HASH=MD5"), scanner_string_null, NULL }, + { ARRAY, make_scanner_string("--HASH=MURMUR"), scanner_string_null, NULL }, { NIL, scanner_string_null, scanner_string_null, NULL} }; @@ -249,7 +253,10 @@ static test_return_t _test_option(scanner_variable_t *scanner, bool test_true= t rc= memcached_parse_configuration(memc, ptr->option.c_str, ptr->option.size); if (test_true) { - test_true_got(rc == MEMCACHED_SUCCESS, memcached_last_error_message(memc)); + if (rc != MEMCACHED_SUCCESS) + memcached_error_print(memc); + + test_true(rc == MEMCACHED_SUCCESS); if (ptr->check_func) { -- 2.30.2