diff options
author | Brian Aker <brian@tangent.org> | 2013-06-12 00:11:22 -0700 |
---|---|---|
committer | Brian Aker <brian@tangent.org> | 2013-06-12 00:11:22 -0700 |
commit | 564d0ca1655236d1b8aeb8b271532e2b065a3ff8 (patch) | |
tree | 5a6692e86eff6243c6536ee60fde0c77586ca078 | |
parent | 26b72ba3ad4ad34cde00a5cd87febcbaa093470d (diff) | |
download | libmemcached-564d0ca1655236d1b8aeb8b271532e2b065a3ff8.tar.gz |
Fix compile issues and version number (which has to be a number).
39 files changed, 835 insertions, 215 deletions
diff --git a/configure.ac b/configure.ac index fa5f33cb..e87c2d0e 100644 --- a/configure.ac +++ b/configure.ac @@ -88,6 +88,7 @@ AM_CONDITIONAL([BUILDING_LIBMEMCACHED],[true]) AM_CONDITIONAL([HAVE_LIBMEMCACHED],[false]) AM_CONDITIONAL([HAVE_LIBDRIZZLE],[false]) AC_DEFINE([HAVE_LIBMEMCACHED],[1],[Enables libmemcached Support]) +AC_SUBST([LIBMEMCACHED_CFLAGS]) AM_CONDITIONAL([BUILDING_GEARMAN],[false]) diff --git a/docs/include.am b/docs/include.am index f28079f8..7b6095b1 100644 --- a/docs/include.am +++ b/docs/include.am @@ -43,59 +43,59 @@ install-html-local: html-local @cp -r ${top_builddir}/html $(htmldir)/ html-local: docs/conf.py - @PYTHONPATH=${top_srcdir}/docs $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) ${top_builddir}/html + @PYTHONPATH=${top_srcdir}/docs @SPHINXBUILD@ -b html $(ALLSPHINXOPTS) ${top_builddir}/html singlehtml: html-local - @PYTHONPATH=${top_srcdir}/docs $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/singlehtml + @PYTHONPATH=${top_srcdir}/docs @SPHINXBUILD@ -b singlehtml $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/singlehtml pickle: docs/conf.py - PYTHONPATH=${top_srcdir}/docs $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/pickle + PYTHONPATH=${top_srcdir}/docs @SPHINXBUILD@ -b pickle $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: docs/conf.py - PYTHONPATH=${top_srcdir}/docs $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/json + PYTHONPATH=${top_srcdir}/docs @SPHINXBUILD@ -b json $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: docs/conf.py - PYTHONPATH=${top_srcdir}/docs $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/htmlhelp + PYTHONPATH=${top_srcdir}/docs @SPHINXBUILD@ -b htmlhelp $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(SPHINX_BUILDDIR)/htmlhelp." epub: docs/conf.py - PYTHONPATH=${top_srcdir}/docs $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/epub + PYTHONPATH=${top_srcdir}/docs @SPHINXBUILD@ -b epub $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(SPHINX_BUILDDIR)/epub." latex: docs/conf.py - PYTHONPATH=${top_srcdir}/docs $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/latex + PYTHONPATH=${top_srcdir}/docs @SPHINXBUILD@ -b latex $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(SPHINX_BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: latex - PYTHONPATH=${top_srcdir}/docs $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/latex + PYTHONPATH=${top_srcdir}/docs @SPHINXBUILD@ -b latex $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." make -C $(SPHINX_BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(SPHINX_BUILDDIR)/latex." text: docs/conf.py - @PYTHONPATH=${top_srcdir}/docs $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/text + @PYTHONPATH=${top_srcdir}/docs @SPHINXBUILD@ -b text $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/text man: - @PYTHONPATH=$(SPHINX_BUILDDIR)/docs $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) ${top_builddir}/man + @PYTHONPATH=$(SPHINX_BUILDDIR)/docs @SPHINXBUILD@ -b man $(ALLSPHINXOPTS) ${top_builddir}/man changes: docs/conf.py - @PYTHONPATH=${top_srcdir}/docs $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/changes + @PYTHONPATH=${top_srcdir}/docs @SPHINXBUILD@ -b changes $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/changes linkcheck: docs/conf.py - PYTHONPATH=${top_srcdir}/docs $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/linkcheck + PYTHONPATH=${top_srcdir}/docs @SPHINXBUILD@ -b linkcheck $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/linkcheck doctest: docs/conf.py - PYTHONPATH=${top_srcdir}/docs $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/doctest + PYTHONPATH=${top_srcdir}/docs @SPHINXBUILD@ -b doctest $(ALLSPHINXOPTS) $(SPHINX_BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(SPHINX_BUILDDIR)/doctest/output.txt." diff --git a/libmemcached/include.am b/libmemcached/include.am index 1394137b..493a89b5 100644 --- a/libmemcached/include.am +++ b/libmemcached/include.am @@ -20,7 +20,7 @@ noinst_HEADERS+= libmemcached/continuum.hpp noinst_HEADERS+= libmemcached/do.hpp noinst_HEADERS+= libmemcached/encoding_key.h noinst_HEADERS+= libmemcached/error.hpp -noinst_HEADERS+= libmemcached/feature.hpp +noinst_HEADERS+= libmemcached/feature.h noinst_HEADERS+= libmemcached/flag.hpp noinst_HEADERS+= libmemcached/initialize_query.h noinst_HEADERS+= libmemcached/instance.hpp diff --git a/libtest/abort.cc b/libtest/abort.cc index 117c4312..8b130044 100644 --- a/libtest/abort.cc +++ b/libtest/abort.cc @@ -36,6 +36,8 @@ #include <cstdlib> +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" int main(void) { if (1) @@ -45,3 +47,4 @@ int main(void) return 0; } +#pragma GCC diagnostic pop diff --git a/libtest/alarm.cc b/libtest/alarm.cc index 6193fbb3..caa075ed 100644 --- a/libtest/alarm.cc +++ b/libtest/alarm.cc @@ -52,49 +52,57 @@ static const struct itimerval cancel_timer= { default_it_interval, default_it_in void set_alarm() { - if (setitimer(ITIMER_VIRTUAL, &defualt_timer, NULL) == -1) + if (gdb_is_caller() == false) { - Error << "setitimer() failed"; + if (setitimer(ITIMER_VIRTUAL, &defualt_timer, NULL) == -1) + { + Error << "setitimer() failed"; + } } } void set_alarm(long tv_sec, long tv_usec) { // For the moment use any value to YATL_ALARM to cancel alarming. - if (getenv("YATL_ALARM")) + if (gdb_is_caller() == false) { - errno= 0; - tv_sec= strtol(getenv("YATL_ALARM"), (char **) NULL, 10); - - if (errno != 0) + if (getenv("YATL_ALARM")) { - FATAL("Bad value for YATL_ALARM"); + errno= 0; + tv_sec= strtol(getenv("YATL_ALARM"), (char **) NULL, 10); + if (errno != 0) + { + FATAL("Bad value for YATL_ALARM"); + } + else if (tv_sec == 0) + { + cancel_alarm(); + } } - else if (tv_sec == 0) - { - cancel_alarm(); - } - } #ifdef __APPLE__ - struct timeval it_value= { time_t(tv_sec), suseconds_t(tv_usec) }; + struct timeval it_value= { time_t(tv_sec), suseconds_t(tv_usec) }; #else - struct timeval it_value= { tv_sec, tv_usec }; + struct timeval it_value= { tv_sec, tv_usec }; #endif - struct itimerval timer= { default_it_interval, it_value }; + struct itimerval timer= { default_it_interval, it_value }; - if (setitimer(ITIMER_VIRTUAL, &timer, NULL) == -1) - { - Error << "setitimer() failed"; + if (setitimer(ITIMER_VIRTUAL, &timer, NULL) == -1) + { + Error << "setitimer() failed"; + } } } void cancel_alarm() { - if (setitimer(ITIMER_VIRTUAL, &cancel_timer, NULL) == -1) + if (gdb_is_caller() == false) { - Error << "setitimer() failed"; + if (setitimer(ITIMER_VIRTUAL, &cancel_timer, NULL) == -1) + { + Error << "setitimer() failed"; + } } } diff --git a/libtest/client.cc b/libtest/client.cc index c536e9dd..aaee5b88 100644 --- a/libtest/client.cc +++ b/libtest/client.cc @@ -50,16 +50,71 @@ # define MSG_NOSIGNAL 0 #endif +#if defined(HAVE_CYASSL) && HAVE_CYASSL +# include <cyassl/ssl.h> +#endif + +#define CA_CERT_PEM "/home/brian/cyassl/certs/ca-cert.pem" +#define CERT_PEM "/home/brian/cyassl/certs/server-cert.pem" +#define CERT_KEY_PEM "/home/brian/cyassl/certs/server-key.pem" + namespace libtest { SimpleClient::SimpleClient(const std::string& hostname_, in_port_t port_) : _is_connected(false), + _is_ssl(false), _hostname(hostname_), _port(port_), sock_fd(INVALID_SOCKET), - requested_message(1) + _error_file(NULL), + _error_line(0), + requested_message(1), + _ctx_ssl(NULL), + _ssl(NULL) +{ + init_ssl(); +} + +void SimpleClient::init_ssl() +{ + if (_is_ssl) { +#if defined(HAVE_CYASSL) && HAVE_CYASSL + CyaSSL_Init(); + + if ((_ctx_ssl= CyaSSL_CTX_new(CyaTLSv1_client_method())) == NULL) + { + FATAL("CyaSSL_CTX_new error" == NULL); + } + + if (CyaSSL_CTX_load_verify_locations(_ctx_ssl, CA_CERT_PEM, 0) != SSL_SUCCESS) + { + FATAL("CyaSSL_CTX_load_verify_locations(%s) cannot obtain certificate", CA_CERT_PEM); + } + + if (CyaSSL_CTX_use_certificate_file(_ctx_ssl, CERT_PEM, SSL_FILETYPE_PEM) != SSL_SUCCESS) + { + FATAL("CyaSSL_CTX_use_certificate_file(%s) cannot obtain certificate", CERT_PEM); + } + + if (CyaSSL_CTX_use_PrivateKey_file(_ctx_ssl, CERT_KEY_PEM, SSL_FILETYPE_PEM) != SSL_SUCCESS) + { + FATAL("CyaSSL_CTX_use_PrivateKey_file(%s) cannot obtain certificate", CERT_KEY_PEM); + } +#endif // defined(HAVE_CYASSL) && HAVE_CYASSL } +} + +void SimpleClient::error(const char* file_, int line_, const std::string& error_) +{ + _error.clear(); + _error_file= file_; + _error_line= line_; + vchar_t buffer; + buffer.resize(1024); + snprintf(&buffer[0], buffer.size() -1, "%s:%d: %s", file_, line_, error_.c_str()); + _error.append(&buffer[0]); +} bool SimpleClient::ready(int event_) { @@ -78,7 +133,7 @@ bool SimpleClient::ready(int event_) if (ready_fds == -1) { - _error= strerror(errno); + error(__FILE__, __LINE__, strerror(errno)); return false; } else if (ready_fds == 1) @@ -94,12 +149,12 @@ bool SimpleClient::ready(int event_) // We check the value to see what happened wth the socket. if (err == 0) { - _error= "getsockopt() returned no error but poll() indicated one existed"; + error(__FILE__, __LINE__, "getsockopt() returned no error but poll() indicated one existed"); return false; } errno= err; } - _error= strerror(errno); + error(__FILE__, __LINE__, strerror(errno)); return false; } @@ -112,14 +167,13 @@ bool SimpleClient::ready(int event_) } fatal_assert(ready_fds == 0); - _error= "TIMEOUT"; + error(__FILE__, __LINE__, "TIMEOUT"); return false; } struct addrinfo* SimpleClient::lookup() { - struct addrinfo *ai= NULL; struct addrinfo hints; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_socktype= SOCK_STREAM; @@ -130,32 +184,42 @@ struct addrinfo* SimpleClient::lookup() (void)snprintf(&service[0], service.size(), "%d", _port); int getaddrinfo_error; - if ((getaddrinfo_error= getaddrinfo(_hostname.c_str(), &service[0], &hints, &ai)) != 0) + if ((getaddrinfo_error= getaddrinfo(_hostname.c_str(), &service[0], &hints, &_ai)) != 0) { if (getaddrinfo_error != EAI_SYSTEM) { - _error= gai_strerror(getaddrinfo_error); + error(__FILE__, __LINE__, gai_strerror(getaddrinfo_error)); return NULL; } else { - _error= strerror(getaddrinfo_error); + error(__FILE__, __LINE__, strerror(getaddrinfo_error)); return NULL; } } - return ai; + return _ai; } SimpleClient::~SimpleClient() { + free_addrinfo(); close_socket(); +#if defined(HAVE_CYASSL) && HAVE_CYASSL + CyaSSL_CTX_free(_ctx_ssl); + _ctx_ssl= NULL; +#endif } void SimpleClient::close_socket() { if (sock_fd != INVALID_SOCKET) { +#if defined(HAVE_CYASSL) && HAVE_CYASSL + CyaSSL_shutdown(_ssl); + CyaSSL_free(_ssl); + _ssl= NULL; +#endif close(sock_fd); sock_fd= INVALID_SOCKET; } @@ -164,11 +228,10 @@ void SimpleClient::close_socket() bool SimpleClient::instance_connect() { _is_connected= false; - struct addrinfo *ai; - if ((ai= lookup())) + if (lookup()) { { - struct addrinfo* address_info_next= ai; + struct addrinfo* address_info_next= _ai; while (address_info_next and sock_fd == INVALID_SOCKET) { @@ -193,7 +256,11 @@ bool SimpleClient::instance_connect() } close_socket(); - _error= strerror(errno); + error(__FILE__, __LINE__, strerror(errno)); + } + else + { + return true; } } else @@ -203,12 +270,12 @@ bool SimpleClient::instance_connect() address_info_next= address_info_next->ai_next; } - freeaddrinfo(ai); + free_addrinfo(); } if (sock_fd == INVALID_SOCKET) { - fatal_assert(_error.size()); + fatal_assert(is_error()); } return bool(sock_fd != INVALID_SOCKET); @@ -222,7 +289,31 @@ bool SimpleClient::is_valid() _error.clear(); if (sock_fd == INVALID_SOCKET) { - return instance_connect(); + if (instance_connect()) + { +#if defined(HAVE_CYASSL) && HAVE_CYASSL + if (_ctx_ssl) + { + _ssl= CyaSSL_new(_ctx_ssl); + if (_ssl == NULL) + { + error(__FILE__, __LINE__, "CyaSSL_new failed"); + return false; + } + + int ssl_error; + if ((ssl_error= CyaSSL_set_fd(_ssl, sock_fd)) != SSL_SUCCESS) + { + error(__FILE__, __LINE__, "CyaSSL_set_fd() should not be returning an error."); + return false; + } + } +#endif + + return true; + } + + return false; } return true; @@ -237,12 +328,40 @@ bool SimpleClient::message(const char* ptr, const size_t len) off_t offset= 0; do { - ssize_t nw= send(sock_fd, ptr + offset, len - offset, MSG_NOSIGNAL); + ssize_t nw; +#if defined(HAVE_CYASSL) && HAVE_CYASSL + if (_ssl) + { + nw= CyaSSL_write(_ssl, (const void*)(ptr +offset), int(len -offset)); + if (nw < 0) + { + int sendErr= CyaSSL_get_error(_ssl, 0); + if (sendErr != SSL_ERROR_WANT_WRITE) + { + char errorString[80]; + int err = CyaSSL_get_error(_ssl, 0); + CyaSSL_ERR_error_string(err, errorString); + error(__FILE__, __LINE__, errorString); + } + else + { + error(__FILE__, __LINE__, "SSL_ERROR_WANT_WRITE"); + } + + return false; + } + } + else +#endif + { + nw= send(sock_fd, ptr + offset, len - offset, MSG_NOSIGNAL); + } + if (nw == -1) { if (errno != EINTR) { - _error= strerror(errno); + error(__FILE__, __LINE__, strerror(errno)); return false; } } @@ -256,7 +375,7 @@ bool SimpleClient::message(const char* ptr, const size_t len) } } - fatal_assert(_error.size()); + fatal_assert(is_error()); return false; } @@ -306,12 +425,37 @@ bool SimpleClient::response(libtest::vchar_t& response_) buffer[1]= 0; do { - ssize_t nr= recv(sock_fd, buffer, 1, MSG_NOSIGNAL); + ssize_t nr; +#if defined(HAVE_CYASSL) && HAVE_CYASSL + if (_ssl) + { + nr= CyaSSL_read(_ssl, buffer, 1); + if (_ssl and nr < 0) + { + int readErr = CyaSSL_get_error(_ssl, 0); + if (readErr != SSL_ERROR_WANT_READ) + { + error(__FILE__, __LINE__, "CyaSSL_read failed"); + } + else + { + error(__FILE__, __LINE__, "CyaSSL_read (unknown) failed"); + } + + return false; + } + } + else +#endif + { + nr= recv(sock_fd, buffer, 1, MSG_NOSIGNAL); + } + if (nr == -1) { if (errno != EINTR) { - _error= strerror(errno); + error(__FILE__, __LINE__, strerror(errno)); return false; } } @@ -336,7 +480,7 @@ bool SimpleClient::response(libtest::vchar_t& response_) } } - fatal_assert(_error.size()); + fatal_assert(is_error()); return false; } @@ -353,12 +497,34 @@ bool SimpleClient::response(std::string& response_) buffer[1]= 0; do { - ssize_t nr= recv(sock_fd, buffer, 1, MSG_NOSIGNAL); + ssize_t nr; +#if defined(HAVE_CYASSL) && HAVE_CYASSL + if (_ssl) + { + nr= CyaSSL_read(_ssl, buffer, 1); + if (_ssl and nr < 0) + { + int readErr = CyaSSL_get_error(_ssl, 0); + if (readErr != SSL_ERROR_WANT_READ) + { + error(__FILE__, __LINE__, "CyaSSL_read failed"); + } + else + { + error(__FILE__, __LINE__, "CyaSSL_read (unknown) failed"); + } + + return false; + } + } + else +#endif + nr= recv(sock_fd, buffer, 1, MSG_NOSIGNAL); if (nr == -1) { if (errno != EINTR) { - _error= strerror(errno); + error(__FILE__, __LINE__, strerror(errno)); return false; } } @@ -382,7 +548,7 @@ bool SimpleClient::response(std::string& response_) } } - fatal_assert(_error.size()); + fatal_assert(is_error()); return false; } diff --git a/libtest/client.hpp b/libtest/client.hpp index 979a532a..1f265608 100644 --- a/libtest/client.hpp +++ b/libtest/client.hpp @@ -36,6 +36,10 @@ #pragma once +#if defined(HAVE_CYASSL) && HAVE_CYASSL +# include <cyassl/ssl.h> +#endif + namespace libtest { class SimpleClient { @@ -49,7 +53,9 @@ public: bool response(std::string&); bool response(libtest::vchar_t&); +private: bool is_valid(); +public: const std::string& error() const { @@ -61,20 +67,45 @@ public: return _error.size() ? true : false; } + const char* error_file() const + { + return _error_file; + } + + int error_line() const + { + return _error_line; + } + +private: + void free_addrinfo() + { + freeaddrinfo(_ai); + _ai= NULL; + } + private: // Methods + void error(const char* file, int line, const std::string& error_); void close_socket(); bool instance_connect(); struct addrinfo* lookup(); bool message(const char* ptr, const size_t len); bool ready(int event_); + void init_ssl(); private: bool _is_connected; + bool _is_ssl; std::string _hostname; in_port_t _port; int sock_fd; std::string _error; + const char* _error_file; + int _error_line; int requested_message; + struct CYASSL_CTX* _ctx_ssl; + struct CYASSL* _ssl; + struct addrinfo *_ai; }; } // namespace libtest diff --git a/libtest/cmdline.cc b/libtest/cmdline.cc index 94c41814..88e1fbb4 100644 --- a/libtest/cmdline.cc +++ b/libtest/cmdline.cc @@ -388,28 +388,56 @@ bool Application::slurp() } bool data_was_read= false; - if (fds[0].revents & POLLRDNORM) + if (fds[0].revents) { - if (stdout_fd.read(_stdout_buffer) == true) + if (fds[0].revents & POLLRDNORM) { - data_was_read= true; + if (stdout_fd.read(_stdout_buffer) == true) + { + data_was_read= true; + } + } + + if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) + { + stdout_fd.close(); + + if (fds[0].revents & POLLERR) + { + Error << "getsockopt(stdout)"; + } } } - if (fds[1].revents & POLLRDNORM) + if (fds[1].revents) { - if (stderr_fd.read(_stderr_buffer) == true) + if (fds[1].revents & POLLRDNORM) + { + if (stderr_fd.read(_stderr_buffer) == true) + { + data_was_read= true; + } + } + + if (fds[1].revents & (POLLERR | POLLHUP | POLLNVAL)) { - data_was_read= true; + stderr_fd.close(); + + if (fds[1].revents & POLLERR) + { + Error << "getsockopt(stderr)"; + } } } return data_was_read; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" Application::error_t Application::join() { - pid_t waited_pid= waitpid(_pid, &_status, WUNTRACED); + pid_t waited_pid= waitpid(_pid, &_status, 0); slurp(); if (waited_pid == _pid and WIFEXITED(_status) == false) { @@ -505,6 +533,7 @@ Application::error_t Application::join() return _app_exit_state; } +#pragma GCC diagnostic pop void Application::add_long_option(const std::string& name, const std::string& option_value) { @@ -546,6 +575,25 @@ int Application::Pipe::Pipe::fd() return _pipe_fd[WRITE]; // STDIN_FILENO } +void Application::Pipe::Pipe::close() +{ + if (_std_fd == STDOUT_FILENO) + { + ::close(_pipe_fd[READ]); + _pipe_fd[READ]= -1; + } + else if (_std_fd == STDERR_FILENO) + { + ::close(_pipe_fd[READ]); + _pipe_fd[READ]= -1; + } + else + { + ::close(_pipe_fd[WRITE]); + _pipe_fd[WRITE]= -1; + } +} + bool Application::Pipe::read(libtest::vchar_t& arg) { @@ -596,7 +644,7 @@ void Application::Pipe::nonblock() if (flags == -1) { Error << "fcntl(F_GETFL) " << strerror(errno); - throw strerror(errno); + throw std::runtime_error(strerror(errno)); } int rval; @@ -608,7 +656,7 @@ void Application::Pipe::nonblock() if (rval == -1) { Error << "fcntl(F_SETFL) " << strerror(errno); - throw strerror(errno); + throw std::runtime_error(strerror(errno)); } } @@ -649,7 +697,7 @@ void Application::Pipe::cloexec() if (flags == -1) { Error << "fcntl(F_GETFD) " << strerror(errno); - throw strerror(errno); + throw std::runtime_error(strerror(errno)); } int rval; @@ -661,7 +709,7 @@ void Application::Pipe::cloexec() if (rval == -1) { Error << "fcntl(F_SETFD) " << strerror(errno); - throw strerror(errno); + throw std::runtime_error(strerror(errno)); } } } @@ -731,13 +779,26 @@ void Application::create_argv(const char *args[]) vchar::append(built_argv, "--leak-check=yes"); #if 0 vchar::append(built_argv, "--show-reachable=yes")); -#endif vchar::append(built_argv, "--track-fds=yes"); +#endif #if 0 built_argv[x++]= strdup("--track-origin=yes"); #endif vchar::append(built_argv, "--malloc-fill=A5"); vchar::append(built_argv, "--free-fill=DE"); + vchar::append(built_argv, "--xml=yes"); + if (getenv("VALGRIND_HOME")) + { + libtest::vchar_t buffer; + buffer.resize(1024); + int length= snprintf(&buffer[0], buffer.size(), "--xml-file=%s/cmd-%%p.xml", getenv("VALGRIND_HOME")); + fatal_assert(length > 0 and size_t(length) < buffer.size()); + vchar::append(built_argv, &buffer[0]); + } + else + { + vchar::append(built_argv, "--xml-file=valgrind-cmd-%p.xml"); + } std::string log_file= create_tmpfile("valgrind"); libtest::vchar_t buffer; diff --git a/libtest/cmdline.h b/libtest/cmdline.h index 368daaec..692363f6 100644 --- a/libtest/cmdline.h +++ b/libtest/cmdline.h @@ -109,6 +109,7 @@ public: ~Pipe(); int fd(); + void close(); enum close_t { READ= 0, diff --git a/libtest/collection.cc b/libtest/collection.cc index 2f1cba31..4b3cace2 100644 --- a/libtest/collection.cc +++ b/libtest/collection.cc @@ -60,6 +60,7 @@ static test_return_t runner_code(libtest::Framework* frame, // system. catch (const libtest::fatal& e) { + alarm(0); if (libtest::fatal::is_disabled()) { libtest::fatal::increment_disabled_counter(); @@ -70,6 +71,11 @@ static test_return_t runner_code(libtest::Framework* frame, throw; } } + catch (...) + { + alarm(0); + throw; + } _timer.sample(); diff --git a/libtest/cpu.cc b/libtest/cpu.cc index 838804d7..b75684b3 100644 --- a/libtest/cpu.cc +++ b/libtest/cpu.cc @@ -2,7 +2,7 @@ * * Data Differential YATL (i.e. libtest) library * - * Copyright (C) 2012 Data Differential, http://datadifferential.com/ + * Copyright (C) 2012-2013 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 @@ -34,8 +34,11 @@ * */ -#include "libtest/yatlcon.h" -#include <libtest/common.h> +#ifdef HAVE_CONFIG_H +# include "libtest/yatlcon.h" +#endif + +#include "libtest/cpu.hpp" #include <unistd.h> @@ -47,23 +50,21 @@ namespace libtest { -size_t number_of_cpus() +uint32_t number_of_cpus() { - size_t number_of_cpu= 1; -#if defined(TARGET_OS_LINUX) && TARGET_OS_LINUX + uint32_t number_of_cpu= 1; +#ifdef linux number_of_cpu= sysconf(_SC_NPROCESSORS_ONLN); #elif defined(HAVE_SYS_SYSCTL_H) && defined(CTL_HW) && defined(HW_NCPU) && defined(HW_AVAILCPU) && defined(HW_NCPU) int mib[4]; size_t len= sizeof(number_of_cpu); /* set the mib for hw.ncpu */ - mib[0] = CTL_HW; - mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU; + mib[0]= CTL_HW; + mib[1]= HW_AVAILCPU; // alternatively, try HW_NCPU; /* get the number of CPUs from the system */ - sysctl(mib, 2, &number_of_cpu, &len, NULL, 0); - - if (number_of_cpu < 1) + if (sysctl(mib, 2, &number_of_cpu, &len, NULL, 0) == -1) { mib[1]= HW_NCPU; sysctl(mib, 2, &number_of_cpu, &len, NULL, 0 ); diff --git a/libtest/cpu.hpp b/libtest/cpu.hpp index 41277096..a435b0f4 100644 --- a/libtest/cpu.hpp +++ b/libtest/cpu.hpp @@ -36,8 +36,10 @@ #pragma once +#include <cstdlib> + namespace libtest { -size_t number_of_cpus(); +uint32_t number_of_cpus(); } // namespace libtest diff --git a/libtest/drizzled.cc b/libtest/drizzled.cc index 3a93b666..3887e3ce 100644 --- a/libtest/drizzled.cc +++ b/libtest/drizzled.cc @@ -166,6 +166,11 @@ public: return true; } + bool is_valgrind() const + { + return false; + } + bool has_port_option() const { return true; diff --git a/libtest/error.h b/libtest/error.h index f567d2a3..d1168b40 100644 --- a/libtest/error.h +++ b/libtest/error.h @@ -52,3 +52,77 @@ static inline bool test_failed(test_return_t rc) { return (rc != TEST_SUCCESS); } + +namespace libtest { + +class Error +{ + public: + Error(): + _is_error(false), + _file(NULL), + _line(-1), + _func(NULL) + { + } + + Error(const Error& error_): + _is_error(false), + _file(NULL), + _line(0), + _func(NULL) + { + if (error_.is_error()) + { + _is_error= true; + _file= error_.file(); + _line= error_.line(); + _func= error_.func(); + _message= error_.error(); + } + } + + Error(const char* file_, int line_, const char* func_, const std::string& message_): + _is_error(true), + _file(file_), + _line(line_), + _func(func_), + _message(message_) + { + } + + bool is_error() const + { + return _is_error; + } + + const char* func() const + { + return _func; + } + + const char* file() const + { + return _file; + } + + int line() const + { + return _line; + } + + const std::string& error() const + { + return _message; + } + + private: + bool _is_error; + const char* _file; + int _line; + const char* _func; + std::string _message; +}; + +} // namespace libtest + diff --git a/libtest/framework.cc b/libtest/framework.cc index 2c9ba74b..f32a759d 100644 --- a/libtest/framework.cc +++ b/libtest/framework.cc @@ -39,10 +39,69 @@ #include <libtest/common.h> #include <libtest/collection.h> #include <libtest/signal.h> +#include <libtest/stream.h> #include <algorithm> +#include <cerrno> #include <fnmatch.h> #include <iostream> +#include <set> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +namespace { +#if defined(DEBUG) && DEBUG + int open_file_descriptors(std::set<int>& pre_existing_fd, const bool report) + { + int max= getdtablesize(); + + int counter= 0; + + for (int x= 3; x < max; ++x) + { + struct stat stats; + + if (fstat(x, &stats) == 0) + { + if (report) + { + std::set<int>::iterator it= pre_existing_fd.find(x); + if (it!= pre_existing_fd.end()) + { } + else + { + std::cerr << "FD: " << x; + + if (S_ISREG(stats.st_mode)) + { + std::cerr << " regular file "; + } + else if (S_ISDIR(stats.st_mode)) + { + std::cerr << " directory "; + } + else if (S_ISSOCK(stats.st_mode)) + { + std::cerr << " socket "; + } + + std::cerr << std::endl; + } + } + else + { + pre_existing_fd.insert(x); + } + + ++counter; + } + } + + return counter; + } +#endif // #if defined(DEBUG) && DEBUG +} // namespace namespace libtest { @@ -107,54 +166,70 @@ void Framework::exec() iter != _collection.end() and (_signal.is_shutdown() == false); ++iter) { - if (*iter) + if (_only_run.empty() == false and + fnmatch(_only_run.c_str(), (*iter)->name(), 0)) { - if (_only_run.empty() == false and - fnmatch(_only_run.c_str(), (*iter)->name(), 0)) - { - continue; - } + continue; + } - _total++; + _total++; - try { - switch ((*iter)->exec()) - { - case TEST_FAILURE: - _failed++; - break; - - case TEST_SKIPPED: - _skipped++; - break; - - // exec() can return SUCCESS, but that doesn't mean that some tests did - // not fail or get skipped. - case TEST_SUCCESS: - _success++; - break; - } - } - catch (const libtest::fatal& e) - { - _failed++; - stream::cerr(e.file(), e.line(), e.func()) << e.what(); - } - catch (const libtest::disconnected& e) +#if defined(DEBUG) && DEBUG + std::set<int> pre_existing_fd; + int open_fd= 0; + if (DEBUG) + { + open_fd= open_file_descriptors(pre_existing_fd, false); + } +#endif + + try { + switch ((*iter)->exec()) { + case TEST_FAILURE: _failed++; - Error << "Unhandled disconnection occurred:" << e.what(); - throw; + break; + + case TEST_SKIPPED: + _skipped++; + break; + + // exec() can return SUCCESS, but that doesn't mean that some tests did + // not fail or get skipped. + case TEST_SUCCESS: + _success++; + break; } - catch (...) + } + catch (const libtest::fatal& e) + { + _failed++; + stream::cerr(e.file(), e.line(), e.func()) << e.what(); + } + catch (const libtest::disconnected& e) + { + _failed++; + Error << "Unhandled disconnection occurred:" << e.what(); + throw; + } + catch (...) + { + _failed++; + throw; + } + +#if defined(DEBUG) && DEBUG + if (DEBUG) + { + int now_open_fd= open_file_descriptors(pre_existing_fd, true); + + if (open_fd != now_open_fd) { - _failed++; - throw; + Error << "Growing number of file descriptors: " << int(now_open_fd - open_fd); } } +#endif } - - void xml(const std::string& testsuites_name, std::ostream& output); } uint32_t Framework::sum_total() diff --git a/libtest/gearmand.cc b/libtest/gearmand.cc index 852cf194..d9216dc2 100644 --- a/libtest/gearmand.cc +++ b/libtest/gearmand.cc @@ -79,9 +79,14 @@ public: std::string response; bool ret= client.send_message("version", response); + if (ret == false) + { + ASSERT_TRUE_(client.is_error(), "client.send_message() failed but no error was set"); + } + if (client.is_error()) { - error(client.error()); + error(client.error_file(), client.error_line(), client.error()); } return ret; @@ -141,6 +146,12 @@ bool Gearmand::build() add_option("--listen=localhost"); + + if (is_ssl()) + { + add_option("--ssl"); + } + return true; } diff --git a/libtest/has.cc b/libtest/has.cc index 2d9abf6b..1dcc4c26 100644 --- a/libtest/has.cc +++ b/libtest/has.cc @@ -43,11 +43,8 @@ namespace libtest { -bool has_libmemcached_sasl(void) -{ - return false; -} - +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" bool has_libmemcached(void) { #if defined(HAVE_LIBMEMCACHED) && HAVE_LIBMEMCACHED @@ -59,6 +56,7 @@ bool has_libmemcached(void) return false; } +#pragma GCC diagnostic pop bool has_libdrizzle(void) { @@ -72,6 +70,8 @@ bool has_libdrizzle(void) return false; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" bool has_postgres_support(void) { char *getenv_ptr; @@ -86,6 +86,7 @@ bool has_postgres_support(void) return false; } +#pragma GCC diagnostic pop bool has_gearmand() diff --git a/libtest/http.cc b/libtest/http.cc index 29873dc6..87d35a81 100644 --- a/libtest/http.cc +++ b/libtest/http.cc @@ -114,6 +114,8 @@ HTTP::HTTP(const std::string& url_arg) : initialize_curl(); } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" bool GET::execute() { (void)init; @@ -139,7 +141,10 @@ bool GET::execute() return false; } +#pragma GCC diagnostic pop +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" bool POST::execute() { #if defined(HAVE_LIBCURL) && HAVE_LIBCURL @@ -163,7 +168,10 @@ bool POST::execute() return false; } +#pragma GCC diagnostic pop +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" bool TRACE::execute() { #if defined(HAVE_LIBCURL) && HAVE_LIBCURL @@ -188,7 +196,10 @@ bool TRACE::execute() return false; } +#pragma GCC diagnostic pop +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" bool HEAD::execute() { #if defined(HAVE_LIBCURL) && HAVE_LIBCURL @@ -212,6 +223,7 @@ bool HEAD::execute() return false; } +#pragma GCC diagnostic pop } // namespace http } // namespace libtest diff --git a/libtest/include.am b/libtest/include.am index 4d1d8428..74046e4f 100644 --- a/libtest/include.am +++ b/libtest/include.am @@ -115,6 +115,9 @@ libtest_libtest_la_CXXFLAGS= EXTRA_libtest_libtest_la_DEPENDENCIES= libtest_libtest_la_LIBADD= libtest_libtest_la_SOURCES= +libtest_libtest_la_CXXFLAGS+= @LIBMEMCACHED_CFLAGS@ +libtest_libtest_la_LIBADD+= @LIBMEMCACHED_LIB@ +libtest_libtest_la_LIBADD+= @CYASSL_LIB@ libtest_libtest_la_SOURCES+= libtest/alarm.cc libtest_libtest_la_SOURCES+= libtest/binaries.cc diff --git a/libtest/is_local.cc b/libtest/is_local.cc index ef4059c3..0efdbecb 100644 --- a/libtest/is_local.cc +++ b/libtest/is_local.cc @@ -56,5 +56,16 @@ bool is_massive() return _is_massive; } +static bool _is_ssl= false; +void is_ssl(bool arg) +{ + _is_ssl= arg; +} + +bool is_ssl() +{ + return _is_ssl; +} + } // namespace libtest diff --git a/libtest/is_local.hpp b/libtest/is_local.hpp index 08355533..4f48dda0 100644 --- a/libtest/is_local.hpp +++ b/libtest/is_local.hpp @@ -47,4 +47,10 @@ void is_massive(bool); LIBTEST_API bool is_massive(); +LIBTEST_API +void is_ssl(bool); + +LIBTEST_API +bool is_ssl(); + } // namespace libtest diff --git a/libtest/lite.h b/libtest/lite.h index 36f873e8..8e008794 100644 --- a/libtest/lite.h +++ b/libtest/lite.h @@ -2,7 +2,7 @@ * * Data Differential YATL (i.e. libtest) library * - * Copyright (C) 2012 Data Differential, http://datadifferential.com/ + * Copyright (C) 2012-2013 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 @@ -192,6 +192,18 @@ do \ } \ } while (0) +#define ASSERT_NULL(__expression) \ +do \ +{ \ + if ((__expression) != NULL) { \ + if (YATL_FULL) { \ + FAIL("Assertion '%s' != NULL", #__expression);\ + } \ + fprintf(stderr, "\n%s:%d: %s Assertion '%s' != NULL\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, #__expression);\ + exit(EXIT_FAILURE); \ + } \ +} while (0) + #define ASSERT_NULL_(__expression, ...) \ do \ { \ @@ -213,9 +225,9 @@ do \ { \ if ((__expression) == NULL) { \ if (YATL_FULL) { \ - FAIL("Assertion '%s' == NULL", #__expression,);\ + FAIL("Assertion '%s' == NULL", #__expression);\ } \ - fprintf(stderr, "\n%s:%d: %s Assertion '%s' == NULL\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, #__expression,);\ + fprintf(stderr, "\n%s:%d: %s Assertion '%s' == NULL\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, #__expression);\ exit(EXIT_FAILURE); \ } \ } while (0) @@ -285,8 +297,8 @@ do \ { \ size_t __expected_length; \ size_t __actual_length; \ - int ret= yatl_strcmp(__expected_str, __actual_str, &__expected_length, &__actual_length); \ - if (ret) { \ + int __ret= yatl_strcmp(__expected_str, __actual_str, &__expected_length, &__actual_length); \ + if (__ret) { \ if (YATL_FULL) { \ FAIL("Assertion '%.*s' != '%.*s'\n", \ (int)(__expected_length), (__expected_str), \ @@ -304,8 +316,8 @@ do \ { \ size_t __expected_length; \ size_t __actual_length; \ - int ret= yatl_strcmp(__expected_str, __actual_str, &__expected_length, &__actual_length); \ - if (ret) { \ + int __ret= yatl_strcmp(__expected_str, __actual_str, &__expected_length, &__actual_length); \ + if (__ret) { \ size_t ask= snprintf(0, 0, __VA_ARGS__); \ ask++; \ char *buffer= (char*)alloca(sizeof(char) * ask); \ @@ -329,8 +341,8 @@ do \ { \ size_t __expected_length; \ size_t __actual_length; \ - int ret= yatl_strcmp(__expected_str, __actual_str, &__expected_length, &__actual_length); \ - if (ret == 0) { \ + int __ret= yatl_strcmp(__expected_str, __actual_str, &__expected_length, &__actual_length); \ + if (__ret == 0) { \ if (YATL_FULL) { \ FAIL("Assertion '%.*s' == '%.*s'", \ (int)(__expected_length), (__expected_str), \ @@ -348,8 +360,8 @@ do \ { \ size_t __expected_length; \ size_t __actual_length; \ - int ret= yatl_strcmp(__expected_str, __actual_str, &__expected_length, &__actual_length); \ - if (ret == 0) { \ + int __ret= yatl_strcmp(__expected_str, __actual_str, &__expected_length, &__actual_length); \ + if (__ret == 0) { \ size_t ask= snprintf(0, 0, __VA_ARGS__); \ ask++; \ char *buffer= (char*)alloca(sizeof(char) * ask); \ diff --git a/libtest/main.cc b/libtest/main.cc index 46429241..8f83dcc2 100644 --- a/libtest/main.cc +++ b/libtest/main.cc @@ -38,12 +38,13 @@ #include <libtest/common.h> #include <cassert> +#include <cstddef> #include <cstdlib> #include <cstring> #include <ctime> #include <fnmatch.h> -#include <iostream> #include <fstream> +#include <iostream> #include <memory> #include <sys/stat.h> #include <sys/time.h> @@ -81,10 +82,12 @@ static void stats_print(libtest::Framework *frame) #include <getopt.h> #include <unistd.h> -int main(int argc, char *argv[]) +int main(int argc, char *argv[], char* environ_[]) { bool opt_massive= false; + bool opt_ssl= false; unsigned long int opt_repeat= 1; // Run all tests once + bool opt_verbose= false; bool opt_quiet= false; std::string collection_to_run; std::string wildcard; @@ -120,22 +123,27 @@ int main(int argc, char *argv[]) // Options parsing { enum long_option_t { + OPT_LIBYATL_VERBOSE, OPT_LIBYATL_VERSION, OPT_LIBYATL_MATCH_COLLECTION, OPT_LIBYATL_MASSIVE, OPT_LIBYATL_QUIET, OPT_LIBYATL_MATCH_WILDCARD, - OPT_LIBYATL_REPEAT + OPT_LIBYATL_REPEAT, + OPT_LIBYATL_SSL, + OPT_LIBYATL_MAX }; static struct option long_options[]= { + { "verbose", no_argument, NULL, OPT_LIBYATL_VERBOSE }, { "version", no_argument, NULL, OPT_LIBYATL_VERSION }, { "quiet", no_argument, NULL, OPT_LIBYATL_QUIET }, { "repeat", required_argument, NULL, OPT_LIBYATL_REPEAT }, { "collection", required_argument, NULL, OPT_LIBYATL_MATCH_COLLECTION }, { "wildcard", required_argument, NULL, OPT_LIBYATL_MATCH_WILDCARD }, { "massive", no_argument, NULL, OPT_LIBYATL_MASSIVE }, + { "ssl", no_argument, NULL, OPT_LIBYATL_SSL }, { 0, 0, 0, 0 } }; @@ -150,6 +158,10 @@ int main(int argc, char *argv[]) switch (option_rv) { + case OPT_LIBYATL_VERBOSE: + opt_verbose= true; + break; + case OPT_LIBYATL_VERSION: break; @@ -175,6 +187,10 @@ int main(int argc, char *argv[]) wildcard= optarg; break; + case OPT_LIBYATL_SSL: + opt_ssl= true; + break; + case OPT_LIBYATL_MASSIVE: opt_massive= true; break; @@ -190,6 +206,14 @@ int main(int argc, char *argv[]) } } + if (opt_verbose) + { + for (char** ptr= environ_; *ptr; ptr++) + { + Out << *ptr; + } + } + srandom((unsigned int)time(NULL)); errno= 0; @@ -218,16 +242,31 @@ int main(int argc, char *argv[]) } } + if ((bool(getenv("YATL_WILDCARD")))) + { + wildcard= getenv("YATL_WILDCARD"); + } + if ((bool(getenv("YATL_RUN_MASSIVE_TESTS"))) or opt_massive) { opt_massive= true; } + if ((bool(getenv("YATL_SSL"))) or opt_ssl) + { + opt_ssl= true; + } + if (opt_quiet) { close(STDOUT_FILENO); } + if (opt_ssl) + { + is_ssl(opt_ssl); + } + if (opt_massive) { is_massive(opt_massive); @@ -345,7 +384,11 @@ int main(int argc, char *argv[]) std::ofstream xml_file; std::string file_name; - file_name.append(&tmp_directory[0]); + if (getenv("WORKSPACE")) + { + file_name.append(getenv("WORKSPACE")); + file_name.append("/"); + } file_name.append(frame->name()); file_name.append(".xml"); xml_file.open(file_name.c_str(), std::ios::trunc); diff --git a/libtest/memcached.cc b/libtest/memcached.cc index 35040535..9515e718 100644 --- a/libtest/memcached.cc +++ b/libtest/memcached.cc @@ -38,9 +38,6 @@ #include "libtest/common.h" -#include <libmemcached-1.2/memcached.h> -#include <libmemcachedutil-1.2/util.h> - #include <cassert> #include <cerrno> #include <cstdio> @@ -185,6 +182,11 @@ public: return true; } + bool is_valgrind() const + { + return false; + } + // Memcached's pidfile is broken bool broken_pid_file() { diff --git a/libtest/result.hpp b/libtest/result.hpp index 79acbb40..239f13c6 100644 --- a/libtest/result.hpp +++ b/libtest/result.hpp @@ -2,7 +2,7 @@ * * Data Differential YATL (i.e. libtest) library * - * Copyright (C) 2012 Data Differential, http://datadifferential.com/ + * Copyright (C) 2012-2013 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 diff --git a/libtest/server.cc b/libtest/server.cc index d024d054..c5d91e95 100644 --- a/libtest/server.cc +++ b/libtest/server.cc @@ -131,6 +131,7 @@ bool Server::check() { _app.slurp(); _app.check(); + return true; } @@ -194,7 +195,13 @@ bool Server::has_pid() const return (_app.pid() > 1); } +bool Server::is_valgrind() const +{ + return getenv("YATL_VALGRIND_SERVER") or valgrind_is_caller(); +} +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" bool Server::start() { // If we find that we already have a pid then kill it. @@ -220,7 +227,7 @@ bool Server::start() { _app.use_ptrcheck(true); } - else if (getenv("YATL_VALGRIND_SERVER")) + else if (is_valgrind()) { _app.use_valgrind(true); } @@ -321,18 +328,20 @@ bool Server::start() _app.slurp(); if (kill_file(pid_file()) == false) { - throw libtest::disconnected(LIBYATL_DEFAULT_PARAM, + throw libtest::disconnected(error_file(), error_line(), __PRETTY_FUNCTION__, hostname(), port(), - "Failed to kill off server, waited: %u after startup occurred, when pinging failed: %.*s stderr:%.*s", + "ping(%s) additionally failed to kill off server, waited: %u after startup occurred failed: %.*s error:%s stderr:%.*s", + error().c_str(), this_wait, int(_running.size()), _running.c_str(), int(_app.stderr_result_length()), _app.stderr_c_str()); } else { - throw libtest::disconnected(LIBYATL_DEFAULT_PARAM, + throw libtest::disconnected(error_file(), error_line(), __PRETTY_FUNCTION__, hostname(), port(), - "Failed native ping(), pid: %d was alive: %s waited: %u server started, having pid_file. exec: %.*s stderr:%.*s", + "ping(%s) additionally failed pid: %d was alive: %s waited: %u server started, having pid_file. exec: %.*s stderr:%.*s", + error().c_str(), int(_app.pid()), _app.check() ? "true" : "false", this_wait, @@ -342,9 +351,10 @@ bool Server::start() } else { - throw libtest::disconnected(LIBYATL_DEFAULT_PARAM, + throw libtest::disconnected(error_file(), error_line(), __PRETTY_FUNCTION__, hostname(), port(), - "Failed native ping(), pid: %d is alive: %s waited: %u server started. exec: %.*s stderr:%.*s", + "ping(%s), additionally pid: %d is alive: %s waited: %u server started. exec: %.*s stderr:%.*s", + error().c_str(), int(_app.pid()), _app.check() ? "true" : "false", this_wait, @@ -358,6 +368,7 @@ bool Server::start() return has_pid(); } +#pragma GCC diagnostic pop void Server::reset_pid() { diff --git a/libtest/server.h b/libtest/server.h index bbebe957..446e40b6 100644 --- a/libtest/server.h +++ b/libtest/server.h @@ -219,6 +219,23 @@ public: return _error; } + void error(const char* file_, int line_, const std::string& error_) + { + _error_file= file_; + _error_line= line_; + _error= error_; + } + + const char* error_file() const + { + return _error_file; + } + + int error_line() const + { + return _error_line; + } + void error(std::string arg) { _error= arg; @@ -278,7 +295,7 @@ protected: private: bool is_helgrind() const; - bool is_valgrind() const; + virtual bool is_valgrind() const; bool is_debug() const; bool set_log_file(); bool set_socket_file(); @@ -287,6 +304,8 @@ private: bool args(Application&); std::string _error; + const char* _error_file; + int _error_line; uint32_t _timeout; // This number should be high enough for valgrind startup (which is slow) }; diff --git a/libtest/signal.cc b/libtest/signal.cc index 70012f1d..90f33c1b 100644 --- a/libtest/signal.cc +++ b/libtest/signal.cc @@ -88,7 +88,8 @@ void SignalThread::post() void SignalThread::test() { - assert(magic_memory == MAGIC_MEMORY); + fatal_assert(magic_memory == MAGIC_MEMORY); + if (bool(getenv("LIBTEST_IN_GDB")) == false) { assert(sigismember(&set, SIGALRM)); diff --git a/libtest/string.hpp b/libtest/string.hpp index c32c8194..f9cd0af1 100644 --- a/libtest/string.hpp +++ b/libtest/string.hpp @@ -40,6 +40,7 @@ #define test_literal_param util_literal_param #define test_literal_compare_param util_literal_compare_param +#define test_literal_printf_param util_literal_printf_param #define test_literal_param_size util_literal_param_size #define test_string_make_from_cstr util_string_make_from_cstr #define test_string_make_from_array util_string_make_from_array diff --git a/libtest/unittest.cc b/libtest/unittest.cc index bbb56c66..1a0afdbe 100644 --- a/libtest/unittest.cc +++ b/libtest/unittest.cc @@ -80,6 +80,19 @@ static test_return_t VALGRIND_COMMAND_test(void *) return TEST_SUCCESS; } +static test_return_t VALGRIND_CHECK_TEST(void *) +{ + SKIP_IF(bool(getenv("VALGRIND_COMMAND")) == false); + SKIP_IF(bool(getenv("TESTS_ENVIRONMENT")) == false); + + if (getenv("TESTS_ENVIRONMENT") && strstr(getenv("TESTS_ENVIRONMENT"), "valgrind")) + { + ASSERT_TRUE(valgrind_is_caller()); + } + + return TEST_SUCCESS; +} + static test_return_t HELGRIND_COMMAND_test(void *) { test_true(getenv("HELGRIND_COMMAND")); @@ -106,6 +119,8 @@ static test_return_t test_success_test(void *) return TEST_SUCCESS; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" static test_return_t test_throw_success_TEST(void *) { try { @@ -122,6 +137,7 @@ static test_return_t test_throw_success_TEST(void *) return TEST_FAILURE; } +#pragma GCC diagnostic pop static test_return_t test_throw_skip_macro_TEST(void *) { @@ -198,10 +214,10 @@ static test_return_t test_throw_fail_TEST(void *) return TEST_FAILURE; } -#pragma GCC diagnostic ignored "-Wstack-protector" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstack-protector" #ifdef __clang__ -# pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wformat-security" #endif @@ -222,10 +238,25 @@ static test_return_t ASSERT_FALSE__TEST(void *) return TEST_FAILURE; } +#pragma GCC diagnostic pop -#ifdef __clang__ -# pragma GCC diagnostic pop -#endif +static test_return_t ASSERT_NOT_NULL_FAIL_TEST(void *) +{ + const char *valid_ptr= NULL; + try { + ASSERT_NOT_NULL(valid_ptr); + } + catch (const libtest::__failure& e) + { + return TEST_SUCCESS; + } + catch (...) + { + return TEST_FAILURE; + } + + return TEST_FAILURE; +} static test_return_t ASSERT_NEQ_FAIL_TEST(void *) { @@ -272,10 +303,14 @@ static test_return_t ASSERT_FALSE_TEST(void *) static test_return_t test_failure_test(void *) { - return TEST_SKIPPED; // Only run this when debugging - - ASSERT_EQ(1, 2); - return TEST_SUCCESS; + try { + ASSERT_EQ(1, 2); + } + catch (...) + { + return TEST_SUCCESS; + } + return TEST_FAILURE; } static test_return_t local_test(void *) @@ -296,6 +331,7 @@ static test_return_t local_not_test(void *) { return TEST_SKIPPED; +#if 0 std::string temp; const char *ptr; @@ -323,6 +359,7 @@ static test_return_t local_not_test(void *) } return TEST_SUCCESS; +#endif } static test_return_t var_exists_test(void *) @@ -618,7 +655,7 @@ static test_return_t application_doesnotexist_BINARY(void *) true_app.will_fail(); const char *args[]= { "--fubar", 0 }; -#if defined(TARGET_OS_OSX) && TARGET_OS_OSX +#if defined(__APPLE__) && __APPLE__ ASSERT_EQ(Application::INVALID_POSIX_SPAWN, true_app.run(args)); #elif defined(TARGET_OS_FREEBSD) && TARGET_OS_FREEBSD ASSERT_EQ(Application::INVALID_POSIX_SPAWN, true_app.run(args)); @@ -878,8 +915,6 @@ static test_return_t fatal_TEST(void *) { ASSERT_EQ(fatal_calls++, fatal::disabled_counter()); throw libtest::fatal(LIBYATL_DEFAULT_PARAM, "Testing va_args based fatal(): %d", 10); - - return TEST_SUCCESS; } static test_return_t number_of_cpus_TEST(void *) @@ -966,6 +1001,8 @@ static test_return_t check_for_VALGRIND(void *) return TEST_SUCCESS; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" static test_return_t check_for_gearman(void *) { test_skip(true, HAVE_LIBGEARMAN); @@ -988,9 +1025,14 @@ static test_return_t check_for_gearman(void *) return TEST_SUCCESS; } +#pragma GCC diagnostic pop static test_return_t check_for_drizzle(void *) { +#if defined(HAVE_CYASSL) && HAVE_CYASSL + SKIP_IF(HAVE_CYASSL); +#endif + test_skip(true, has_drizzled()); testing_service= "drizzled"; @@ -1027,6 +1069,10 @@ static test_return_t clear_servers(void* object) static test_return_t check_for_memcached(void* object) { +#if defined(HAVE_CYASSL) && HAVE_CYASSL + SKIP_IF(HAVE_CYASSL); +#endif + test_skip(true, has_memcached()); server_startup_st *servers= (server_startup_st*)object; @@ -1058,6 +1104,7 @@ test_st environment_tests[] ={ {"VALGRIND_COMMAND", 0, VALGRIND_COMMAND_test }, {"HELGRIND_COMMAND", 0, HELGRIND_COMMAND_test }, {"GDB_COMMAND", 0, GDB_COMMAND_test }, + {"valgrind_is_caller()", 0, VALGRIND_CHECK_TEST }, {0, 0, 0} }; @@ -1074,6 +1121,7 @@ test_st tests_log[] ={ {"ASSERT_FALSE", false, ASSERT_FALSE_TEST }, {"ASSERT_NEQ", false, ASSERT_NEQ_TEST }, {"ASSERT_NEQ FAIL", false, ASSERT_NEQ_FAIL_TEST }, + {"ASSERT_NOT_NULL FAIL", false, ASSERT_NOT_NULL_FAIL_TEST }, {0, 0, 0} }; diff --git a/m4/ax_prog_sphinx_build.m4 b/m4/ax_prog_sphinx_build.m4 index 3a89a331..099f3e15 100644 --- a/m4/ax_prog_sphinx_build.m4 +++ b/m4/ax_prog_sphinx_build.m4 @@ -19,26 +19,29 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 3 +#serial 4 AC_DEFUN([AX_PROG_SPHINX_BUILD], - [AX_WITH_PROG([SPHINXBUILD],[sphinx-build],[:]) - AS_IF([test x"SPHINXBUILD" = x":"], - [SPHINXBUILD=], - [AS_IF([test -x "$SPHINXBUILD"], - [AC_MSG_CHECKING([Checking to see if $SPHINXBUILD is recent]) - junk=`$SPHINXBUILD &> version_file` - ax_sphinx_build_version=`head -1 version_file` - rm version_file - AC_MSG_RESULT([$SPHINXBUILD is version "$ax_sphinx_build_version"]) - $SPHINXBUILD -Q -C -b man -d conftest.d . . >/dev/null 2>&1 - AS_IF([test $? -eq 0], ,[SPHINXBUILD=]) - rm -rf conftest.d - ]) - ]) + [AX_WITH_PROG([SPHINXBUILD],[sphinx-build],[:]) + AS_IF([test x"SPHINXBUILD" = x":"], + [SPHINXBUILD=], + [AS_IF([test -x "$SPHINXBUILD"], + [AC_MSG_CHECKING([Checking to see if $SPHINXBUILD is recent]) + junk=`$SPHINXBUILD --version &> version_file` + AS_IF([test $? -eq 0], + [ax_sphinx_build_version=`head -1 version_file`], + [junk=`$SPHINXBUILD &> version_file` + ax_sphinx_build_version=`head -1 version_file` + rm version_file + AC_MSG_RESULT([$SPHINXBUILD is version "$ax_sphinx_build_version"]) + $SPHINXBUILD -Q -C -b man -d conftest.d . . >/dev/null 2>&1 + AS_IF([test $? -eq 0], ,[SPHINXBUILD=]) + rm -rf conftest.d ]) + ]) + ]) - AS_IF([test -n "${SPHINXBUILD}"], - [AC_SUBST([SPHINXBUILD]) - ifelse([$1], , :, [$1])], - [ifelse([$2], , :, [$2])]) - ]) + AS_IF([test -n "${SPHINXBUILD}"], + [AC_SUBST([SPHINXBUILD]) + ifelse([$1], , :, [$1])], + [ifelse([$2], , :, [$2])]) + ]) diff --git a/tests/keys.hpp b/tests/keys.hpp index 1034a672..99ced4ab 100644 --- a/tests/keys.hpp +++ b/tests/keys.hpp @@ -39,6 +39,8 @@ #include <uuid/uuid.h> #endif +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" struct keys_st { public: keys_st(size_t arg) @@ -143,3 +145,4 @@ private: libtest::vchar_ptr_t _keys; std::vector<size_t> _lengths; }; +#pragma GCC diagnostic pop diff --git a/tests/libmemcached-1.0/all_tests.cc b/tests/libmemcached-1.0/all_tests.cc index a471d89a..045c426e 100644 --- a/tests/libmemcached-1.0/all_tests.cc +++ b/tests/libmemcached-1.0/all_tests.cc @@ -83,7 +83,7 @@ void get_world(libtest::Framework* world) { // Assume a minimum of 3, and a maximum of 8 world->servers().set_servers_to_run((libtest::number_of_cpus() > 3) ? - std::min(libtest::number_of_cpus(), size_t(8)) : 3); + std::min(libtest::number_of_cpus(), uint32_t(8)) : 3); } world->collections(collection); diff --git a/tests/libmemcached-1.0/generate.cc b/tests/libmemcached-1.0/generate.cc index a0d19c49..39e5d9fe 100644 --- a/tests/libmemcached-1.0/generate.cc +++ b/tests/libmemcached-1.0/generate.cc @@ -113,6 +113,8 @@ test_return_t generate_data(memcached_st *memc) return TEST_SUCCESS; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" test_return_t generate_data_with_stats(memcached_st *memc) { test_compare(TEST_SUCCESS, generate_pairs(memc)); @@ -147,6 +149,7 @@ test_return_t generate_data_with_stats(memcached_st *memc) return TEST_SUCCESS; } +#pragma GCC diagnostic pop test_return_t generate_buffer_data(memcached_st *memc) { diff --git a/tests/libmemcached-1.0/pool.cc b/tests/libmemcached-1.0/pool.cc index 577c0e94..174e197f 100644 --- a/tests/libmemcached-1.0/pool.cc +++ b/tests/libmemcached-1.0/pool.cc @@ -252,10 +252,12 @@ static __attribute__((noreturn)) void* connection_release(void *arg) pthread_exit(arg); } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunreachable-code" test_return_t connection_pool3_test(memcached_st *memc) { #ifdef __APPLE__ - return TEST_SKIPPED; + SKIP_IF(__APPLE__); #endif memcached_pool_st* pool= memcached_pool_create(memc, 1, 1); @@ -321,6 +323,7 @@ test_return_t connection_pool3_test(memcached_st *memc) return TEST_SUCCESS; } +#pragma GCC diagnostic pop static memcached_st * create_single_instance_memcached(const memcached_st *original_memc, const char *options) { diff --git a/tests/libmemcached-1.0/sasl.cc b/tests/libmemcached-1.0/sasl.cc index 06f9e3db..f3b136f7 100644 --- a/tests/libmemcached-1.0/sasl.cc +++ b/tests/libmemcached-1.0/sasl.cc @@ -64,28 +64,21 @@ static test_return_t pre_sasl(memcached_st *) */ static test_return_t sasl_auth_test(memcached_st *memc) { -#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT - 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; - } -#else - (void)memc; -#endif + SKIP_IF(libmemcached_has_feature(LIBMEMCACHED_FEATURE_HAS_SASL)); + + 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); - return TEST_SKIPPED; + 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; } diff --git a/tests/libmemcached_world.h b/tests/libmemcached_world.h index 6bed25a9..8cf84c6e 100644 --- a/tests/libmemcached_world.h +++ b/tests/libmemcached_world.h @@ -47,7 +47,7 @@ static void *world_create(libtest::server_startup_st& servers, test_return_t& er if (servers.sasl()) { - SKIP_UNLESS(libtest::has_libmemcached_sasl()); + SKIP_UNLESS(libmemcached_has_feature(LIBMEMCACHED_FEATURE_HAS_SASL)); // Assume we are running under valgrind, and bail if (getenv("TESTS_ENVIRONMENT")) diff --git a/tests/memcp.cc b/tests/memcp.cc index 4139437b..d49b1775 100644 --- a/tests/memcp.cc +++ b/tests/memcp.cc @@ -66,7 +66,7 @@ static test_return_t help_test(void *) static test_return_t server_test(void *) { int fd; - std::string tmp_file= create_tmpfile("memcp", fd); + std::string tmp_file= libtest::create_tmpfile("memcp", fd); ASSERT_TRUE(tmp_file.c_str()); struct stat buf; ASSERT_EQ(fstat(fd, &buf), 0); @@ -1 +1 @@ -m4_define([VERSION_NUMBER], [1.1.0-dev]) +m4_define([VERSION_NUMBER], [1.1.0]) |