Merge in libtest updates.
authorBrian Aker <brian@tangent.org>
Wed, 27 Jul 2011 16:56:41 +0000 (09:56 -0700)
committerBrian Aker <brian@tangent.org>
Wed, 27 Jul 2011 16:56:41 +0000 (09:56 -0700)
12 files changed:
libtest/blobslap_worker.cc [new file with mode: 0644]
libtest/blobslap_worker.h [new file with mode: 0644]
libtest/cmdline.cc
libtest/gearmand.cc
libtest/include.am
libtest/killpid.cc
libtest/killpid.h
libtest/server.cc
libtest/signal.cc
libtest/signal.h
libtest/test.cc
libtest/unittest.cc

diff --git a/libtest/blobslap_worker.cc b/libtest/blobslap_worker.cc
new file mode 100644 (file)
index 0000000..2ac07d6
--- /dev/null
@@ -0,0 +1,179 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  libtest
+ *
+ *  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 <libtest/common.h>
+#include <libtest/blobslap_worker.h>
+#include <libtest/killpid.h>
+
+using namespace libtest;
+
+#include <cassert>
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <libgearman/gearman.h>
+
+#ifndef __INTEL_COMPILER
+#pragma GCC diagnostic ignored "-Wold-style-cast"
+#endif
+
+using namespace libtest;
+
+class BlobslapWorker : public Server
+{
+private:
+public:
+  BlobslapWorker(in_port_t port_arg) :
+    Server("localhost", port_arg)
+  { }
+
+  pid_t get_pid(bool error_is_ok)
+  {
+    if (not pid_file().empty())
+    {
+      Wait wait(pid_file(), 0);
+
+      if (error_is_ok and not wait.successful())
+      {
+        Error << "Pidfile was not found:" << pid_file();
+        return -1;
+
+        return get_pid_from_file(pid_file());
+      }
+    }
+
+    return -1;
+  }
+
+  bool ping()
+  {
+    if (pid_file().empty())
+    {
+      Error << "No pid file available";
+      return false;
+    }
+
+    Wait wait(pid_file(), 0);
+    if (not wait.successful())
+    {
+      Error << "Pidfile was not found:" << pid_file();
+      return false;
+    }
+
+    pid_t local_pid= get_pid_from_file(pid_file());
+    if (local_pid <= 0)
+    {
+      return false;
+    }
+
+    if (::kill(local_pid, 0) == 0)
+    {
+      return true;
+    }
+
+    return false;
+  }
+
+  const char *name()
+  {
+    return "blobslap_worker";
+  };
+
+  const char *executable()
+  {
+    return GEARMAND_BLOBSLAP_WORKER;
+  }
+
+  const char *pid_file_option()
+  {
+    return "--pid-file=";
+  }
+
+  const char *daemon_file_option()
+  {
+    return "--daemon";
+  }
+
+  const char *log_file_option()
+  {
+    return NULL;
+  }
+
+  const char *port_option()
+  {
+    return "--port=";
+  }
+
+  bool is_libtool()
+  {
+    return true;
+  }
+
+  bool build(int argc, const char *argv[]);
+};
+
+
+#include <sstream>
+
+bool BlobslapWorker::build(int argc, const char *argv[])
+{
+  std::stringstream arg_buffer;
+
+  for (int x= 1 ; x < argc ; x++)
+  {
+    arg_buffer << " " << argv[x] << " ";
+  }
+
+  set_extra_args(arg_buffer.str());
+
+  return true;
+}
+
+namespace libtest {
+
+Server *build_blobslap_worker(in_port_t try_port)
+{
+  return new BlobslapWorker(try_port);
+}
+
+}
diff --git a/libtest/blobslap_worker.h b/libtest/blobslap_worker.h
new file mode 100644 (file)
index 0000000..96eb426
--- /dev/null
@@ -0,0 +1,43 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  libtest
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+namespace libtest {
+
+Server *build_blobslap_worker(in_port_t try_port);
+
+}
index d7bed82012ccd47283db1fa4a232e2097b147770..afd560b255263da3a6320075db5dccff8358d122 100644 (file)
@@ -38,6 +38,8 @@
 
 #include <libtest/cmdline.h>
 
+using namespace libtest;
+
 #include <cstdlib>
 #include <string>
 #include <sstream>
index f526e015f4c0648690dd19c225bc8596029c96b4..bd9bd14d35177b414d11d956819771b76f21b939 100644 (file)
@@ -208,6 +208,8 @@ bool Gearmand::build(int argc, const char *argv[])
     arg_buffer << " -u root ";
   }
 
+  arg_buffer << " --listen=127.0.0.1 ";
+
   for (int x= 1 ; x < argc ; x++)
   {
     arg_buffer << " " << argv[x] << " ";
index 7cda0f9b9fb91c4e744cf3b4a1bc708df101bee6..57d579bad08cbd8b0637cf6cc5ed6e492baffacf 100644 (file)
@@ -9,12 +9,19 @@
 # All paths should be given relative to the root
 # 
 
-LIBUTEST_TMP = ${abs_top_builddir}/tests/var/tmp/
+LIBTEST_TMP = ${abs_top_builddir}/tests/var/tmp/
 
-VALGRIND_COMMAND= $(LIBTOOL) --mode=execute valgrind --error-exitcode=1 --leak-check=yes --show-reachable=yes --track-fds=yes --malloc-fill=A5 --free-fill=DE
-HELGRIND_COMMAND= $(LIBTOOL) --mode=execute valgrind --tool=helgrind --read-var-info=yes --error-exitcode=1  -v
-DRD_COMMAND= $(LIBTOOL) --mode=execute valgrind --tool=drd
-GDB_COMMAND= $(LIBTOOL) --mode=execute gdb -f -x libtest/run.gdb
+LIBTOOL_COMMAND=$(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
+GDB_COMMAND= $(LIBTOOL_COMMAND) gdb -f -x libtest/run.gdb
+
+export LIBTOOL_COMMAND
+export VALGRIND_COMMAND
+export HELGRIND_COMMAND
+export DRD_COMMAND
+export GDB_COMMAND
 
 EXTRA_DIST+= libtest/run.gdb
 
@@ -24,11 +31,12 @@ CLEANFILES+= \
             tests/var/tmp/*
 
 noinst_HEADERS+= \
+                libtest/blobslap_worker.h \
                 libtest/callbacks.h \
                 libtest/cmdline.h \
                 libtest/collection.h \
-                libtest/comparison.hpp \
                 libtest/common.h \
+                libtest/comparison.hpp \
                 libtest/core.h \
                 libtest/error.h \
                 libtest/failed.h \
@@ -77,34 +85,37 @@ endif
 
 if HAVE_LIBGEARMAN
 LIBTEST_LDADD+= 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
 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/*
 
+tests/var:
+       @$(mkdir_p) tests/var
 
-tests/var: tests/var/log tests/var/tmp tests/var/run clearn-var
-       $(mkdir_p) tests/var
-
-tests/var/log:
-       $(mkdir_p) tests/var/log
+tests/var/log: tests/var
+       @$(mkdir_p) tests/var/log
 
-tests/var/tmp:
-       $(mkdir_p) tests/var/tmp
+tests/var/tmp: tests/var
+       @$(mkdir_p) tests/var/tmp
 
-tests/var/run:
-       $(mkdir_p) tests/var/run
+tests/var/run: tests/var
+       @$(mkdir_p) tests/var/run
 
 .PHONY+= tests/var
 
 
 libtest_unittest_CFLAGS=
 libtest_unittest_LDADD= ${LIBTEST_LDADD}
-libtest_unittest_DEPENDENCIES= ${LIBTEST_LDADD}
+libtest_unittest_DEPENDENCIES= ${LIBTEST_LDADD} libtest_tmp_dir
 libtest_unittest_SOURCES= libtest/unittest.cc
 check_PROGRAMS+= libtest/unittest
 noinst_PROGRAMS+= libtest/unittest
index bc9a55941d7b8e5817395cc19a34cea9a0ef1c83..1d5992db175cd486b2897de1c7f10ce85155c6b1 100644 (file)
@@ -99,12 +99,13 @@ bool kill_pid(pid_t pid_arg)
 }
 
 
-void kill_file(const std::string &filename)
+pid_t kill_file(const std::string &filename)
 {
+  pid_t ret= -1;
   FILE *fp;
 
   if (filename.empty())
-    return;
+    return ret;
 
   if ((fp= fopen(filename.c_str(), "r")))
   {
@@ -123,4 +124,37 @@ void kill_file(const std::string &filename)
       }
     }
   }
+  
+  return ret;
+}
+
+pid_t get_pid_from_file(const std::string &filename)
+{
+  pid_t ret= -1;
+  FILE *fp;
+
+  if (filename.empty())
+  {
+    Error << "empty pid file";
+    return ret;
+  }
+
+  if ((fp= fopen(filename.c_str(), "r")))
+  {
+    char pid_buffer[1024];
+
+    char *ptr= fgets(pid_buffer, sizeof(pid_buffer), fp);
+    fclose(fp);
+
+    if (ptr)
+    {
+      ret= (pid_t)atoi(pid_buffer);
+      if (ret <= 0)
+      {
+        return ret;
+      }
+    }
+  }
+  
+  return ret;
 }
index d67ec94b9770b599cf3debe1a276e77abeef3126..12c438e5f391a9c85ef47f2045304154ecb64b3f 100644 (file)
@@ -39,4 +39,6 @@
 
 bool kill_pid(pid_t pid_arg);
 
-void kill_file(const std::string &filename);
+pid_t kill_file(const std::string &filename);
+
+pid_t get_pid_from_file(const std::string &filename);
index d5329b11971851b1e04c50fa28aeb2735443d38a..bf962e42b469200c3977989993f9da074cbf8046 100644 (file)
@@ -58,6 +58,7 @@ static inline std::string &rtrim(std::string &s)
 
 #ifdef HAVE_LIBGEARMAN
 #include <libtest/gearmand.h>
+#include <libtest/blobslap_worker.h>
 #endif
 
 #ifdef HAVE_LIBMEMCACHED
@@ -324,23 +325,26 @@ bool Server::set_log_file()
 void Server::rebuild_base_command()
 {
   _base_command.clear();
-  if (is_libtool())
+  if (is_libtool() and getenv("LIBTOOL_COMMAND"))
   {
-    _base_command+= "./libtool --mode=execute ";
+    _base_command+= getenv("LIBTOOL_COMMAND");
+    _base_command+= " ";
   }
 
-  if (is_debug())
+  if (is_debug() and getenv("GDB_COMMAND"))
   {
-    _base_command+= "gdb ";
+    _base_command+= getenv("GDB_COMMAND");
+    _base_command+= " ";
   }
-  else if (is_valgrind())
+  else if (is_valgrind() and getenv("VALGRIND_COMMAND"))
   {
-    _base_command+= "valgrind --log-file=tests/var/tmp/valgrind.out --error-exitcode=1 --leak-check=yes --show-reachable=yes --track-fds=yes --malloc-fill=A5 --free-fill=DE ";
-
+    _base_command+= getenv("VALGRIND_COMMAND");
+    _base_command+= " ";
   }
-  else if (is_helgrind())
+  else if (is_helgrind() and getenv("HELGRIND_COMMAND"))
   {
-    _base_command+= "valgrind --log-file=tests/var/tmp/helgrind.out --tool=helgrind --read-var-info=yes --error-exitcode=1  -v ";
+    _base_command+= getenv("HELGRIND_COMMAND");
+    _base_command+= " ";
   }
 
   _base_command+= executable();
@@ -359,7 +363,9 @@ bool Server::args(std::string& options)
   if (getenv("LIBTEST_LOG") and log_file_option())
   {
     if (not set_log_file())
+    {
       return false;
+    }
 
     arg_buffer << " " << log_file_option() << _log_file;
   }
@@ -368,7 +374,9 @@ bool Server::args(std::string& options)
   if (pid_file_option())
   {
     if (not set_pid_file())
+    {
       return false;
+    }
 
     arg_buffer << " " << pid_file_option() << pid_file(); 
   }
@@ -382,7 +390,9 @@ bool Server::args(std::string& options)
   if (_is_socket and socket_file_option())
   {
     if (not set_socket_file())
+    {
       return false;
+    }
 
     arg_buffer << " " << socket_file_option() << "\"" <<  _socket << "\"";
   }
@@ -396,7 +406,9 @@ bool Server::args(std::string& options)
   options+= arg_buffer.str();
 
   if (not _extra_args.empty())
+  {
     options+= _extra_args;
+  }
 
   return true;
 }
@@ -544,6 +556,18 @@ bool server_startup(server_startup_st& construct, const std::string& server_type
   #endif
 #else
     Error << "No gearmand binary is available";
+#endif
+  }
+  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
   }
   else if (server_type.compare("memcached") == 0)
index 45d0fd9ec923dcb5c30007b7f0f986f5299b8a4e..263d183a2b4d7022f333529d6dbbbdbb0b6cba00 100644 (file)
@@ -62,10 +62,11 @@ void SignalThread::set_shutdown(shutdown_t arg)
 
   if (arg == SHUTDOWN_GRACEFUL)
   {
-    pthread_kill(thread, SIGUSR2);
-
-    void *retval;
-    pthread_join(thread, &retval);
+    if (pthread_kill(thread, SIGUSR2) == 0)
+    {
+      void *retval;
+      pthread_join(thread, &retval);
+    }
   }
 }
 
@@ -96,6 +97,16 @@ void SignalThread::test()
   assert(sigismember(&set, SIGUSR2));
 }
 
+SignalThread::~SignalThread()
+{
+  if (pthread_equal(thread, pthread_self()) != 0 and (pthread_kill(thread, 0) == ESRCH) == true)
+  {
+    void *retval;
+    pthread_join(thread, &retval);
+  }
+  sem_destroy(&lock);
+}
+
 extern "C" {
 
 static void *sig_thread(void *arg)
@@ -123,7 +134,6 @@ static void *sig_thread(void *arg)
     case SIGQUIT:
       if (context->is_shutdown() == false)
       {
-        Error << "Signal handling thread got signal " <<  strsignal(sig);
         context->set_shutdown(SHUTDOWN_FORCED);
       }
       break;
@@ -140,7 +150,8 @@ static void *sig_thread(void *arg)
 }
 
 SignalThread::SignalThread() :
-  magic_memory(MAGIC_MEMORY)
+  magic_memory(MAGIC_MEMORY),
+  thread(pthread_self())
 {
   pthread_mutex_init(&shutdown_mutex, NULL);
   sigemptyset(&set);
index eb0928256683cebea29266f57131c0c8e086f540..d87d4f4e82abb3ec45155e618db789f68f6b4197 100644 (file)
@@ -69,10 +69,7 @@ public:
     return sigwait(&set, &sig);
   }
 
-  ~SignalThread()
-  {
-    sem_destroy(&lock);
-  }
+  ~SignalThread();
 
   void set_shutdown(shutdown_t arg);
   bool is_shutdown();
index d71057d36bdf14f8f93457a644d5a96b771585fe..d113740fca1b8e25e6fce2e94ba6dfa338b4e79d 100644 (file)
@@ -94,6 +94,11 @@ void set_default_socket(const char *socket)
 
 static void stats_print(Stats *stats)
 {
+  if (stats->collection_failed == 0 and stats->collection_success == 0)
+  {
+    return;
+  }
+
   Out << "\tTotal Collections\t\t\t\t" << stats->collection_total;
   Out << "\tFailed Collections\t\t\t\t" << stats->collection_failed;
   Out << "\tSkipped Collections\t\t\t\t" << stats->collection_skipped;
@@ -179,9 +184,21 @@ int main(int argc, char *argv[])
 
   test_return_t error;
   void *creators_ptr= world->create(error);
-  if (test_failed(error))
+
+  switch (error)
   {
-    Error << "create() failed";
+  case TEST_SUCCESS:
+    break;
+
+  case TEST_SKIPPED:
+    Out << "SKIP " << argv[0];
+    delete world;
+    return EXIT_SUCCESS;
+
+  case TEST_FATAL:
+  case TEST_FAILURE:
+  case TEST_MEMORY_ALLOCATION_FAILURE:
+    Error << argv[0] << "create() failed";
     delete world;
     return EXIT_FAILURE;
   }
@@ -368,11 +385,11 @@ cleanup:
     Out << "Some test failed.";
     exit_code= EXIT_FAILURE;
   }
-  else if (stats.collection_skipped)
+  else if (stats.collection_skipped and stats.collection_failed and stats.collection_success)
   {
     Out << "Some tests were skipped.";
   }
-  else
+  else if (stats.collection_success and stats.collection_failed == 0)
   {
     Out << "All tests completed successfully.";
   }
index 1528106b7974443e94fa172a25c5019cbbb6a078..6902d0012190c689d0ea3b10c607e71547796c00 100644 (file)
 #include <libtest/test.hpp>
 
 #include <cstdlib>
+#include <unistd.h>
 
 using namespace libtest;
 
+static test_return_t LIBTOOL_COMMAND_test(void *)
+{
+  test_true(getenv("LIBTOOL_COMMAND"));
+  return TEST_SUCCESS;
+}
+
+static test_return_t VALGRIND_COMMAND_test(void *)
+{
+  test_true(getenv("VALGRIND_COMMAND"));
+  return TEST_SUCCESS;
+}
+
+static test_return_t HELGRIND_COMMAND_test(void *)
+{
+  test_true(getenv("HELGRIND_COMMAND"));
+  return TEST_SUCCESS;
+}
+
+static test_return_t GDB_COMMAND_test(void *)
+{
+  test_true(getenv("GDB_COMMAND"));
+  return TEST_SUCCESS;
+}
+
 static test_return_t test_success_test(void *)
 {
   return TEST_SUCCESS;
@@ -171,6 +196,14 @@ test_st memcached_tests[] ={
   {0, 0, 0}
 };
 
+test_st environment_tests[] ={
+  {"LIBTOOL_COMMAND", 0, LIBTOOL_COMMAND_test },
+  {"VALGRIND_COMMAND", 0, VALGRIND_COMMAND_test },
+  {"HELGRIND_COMMAND", 0, HELGRIND_COMMAND_test },
+  {"GDB_COMMAND", 0, GDB_COMMAND_test },
+  {0, 0, 0}
+};
+
 test_st tests_log[] ={
   {"TEST_SUCCESS", 0, test_success_test },
   {"TEST_FAILURE", 0, test_failure_test },
@@ -184,6 +217,7 @@ test_st local_log[] ={
 };
 
 collection_st collection[] ={
+  {"environment", 0, 0, environment_tests},
   {"return values", 0, 0, tests_log},
   {"local", 0, 0, local_log},
   {"gearmand", 0, 0, gearmand_tests},